【问题标题】:Using *this to initialize a reference使用 *this 初始化引用
【发布时间】:2025-12-30 17:35:15
【问题描述】:

我正在尝试使用其构造函数初始化我的类 ShadeRec 的实例:

ShadeRec(World& world);

所以我传递给它:

ShadeRec sr(*this);

其中“this”是 World 类的一个实例。

我收到以下错误:

World.cpp: In member function ‘ShadeRec World::hitObjects(const Ray&) const’:
World.cpp:52: error: no matching function for call to ‘ShadeRec::ShadeRec(const World&)’
ShadeRec.h:17: note: candidates are: ShadeRec::ShadeRec(const ShadeRec&)
ShadeRec.h:15: note:                 ShadeRec::ShadeRec(World&)

假设问题只是 World 实例具有属性 const,我该如何摆脱此错误消息?

【问题讨论】:

标签: c++ pointers reference constructor argument-passing


【解决方案1】:

您在标记为consthitObjects 成员函数中执行此操作。可以这样想:该成员函数承诺不修改 *this 对象。但是,它很高兴通过非const 引用将其传递给不同的对象。如果其他对象修改了它怎么办?哦哦!

有两种可能的解决方案取决于问题。 ShadeRec 构造函数是否真的修改了传递的World 对象?

  1. 如果是这样,您应该确保hitObjects 未标记为const。毕竟那是在撒谎。

  2. 如果没有,它应该由const World& 接收。那么标记为consthitObjects传递*this给它就可以了。

【讨论】:

  • 它不会修改传入的对象,ShadeRec 用它来初始化 ShadeRec 实例的 World 对象。但是当我将参数更改为 const World& 时,我得到了另一个错误。 ShadeRec.cpp:在构造函数“ShadeRec::ShadeRec(const World&)”中:ShadeRec.cpp:7:错误:从“const World”类型的表达式中对“World&”类型的引用的初始化无效
  • 现在我得到了:Undefined symbols for architecture x86_64: "Point3D::Point3D(Point3D const&)",引用自:ShadeRec::ShadeRec(ShadeRec const&)in cclHIDes.o ShadeRec::ShadeRec cclHIDes.o 中的 (ShadeRec const&) Ray::Ray(Ray const&)in cclHDes.o ld: 未找到架构 x86_64 的符号 collect2: ld 返回 1 个退出状态
  • @RupertCobbe-Warburton 我将首先回复您的第一条评论。你有一个更根本的问题。您正在将*this(即const)传递给新的ShadeRec 对象,该对象保留对象的非const 引用。那根本行不通。为什么ShadeRec 不保留const 参考?或者 hitObjects 不应该是 const 成员函数。
  • @RupertCobbe-Warburton 第二条评论:这意味着您已经声明了 Point3D 复制构造函数但尚未定义它。
  • 是的,我的功能有问题。现在 hitObjects 不是 const。因此是第二条评论。
【解决方案2】:

const 引用和非常量之间存在差异。

编译器不想将常量对象传递给采用非常量(可变)对象的方法。这将违反接口协议:能够修改常量对象。

这种情况可能是由常量对象调用可变函数或常量方法调用可变方法引起的。

【讨论】:

  • 使用 const 引用传递的对象不是常量对象。 const 引用中的单词const 并没有说明对象,它只是表达了引用的一个属性。
【解决方案3】:

class Worldconst 成员函数中的 this 指针的类型是 const World*,这意味着您不能使用它来初始化非常量引用(您不能只是“删除"它的常量)。

ShadeRec的构造函数的参数类型改为const World&

ShadeRec(const World& world);
参见 C++03, 9.3.2 §1:

class X 的成员函数中this 的类型是X*。如果成员函数声明为const,则this的类型为const X*

【讨论】:

  • 它不会修改传入的对象,ShadeRec 用它来初始化 ShadeRec 实例的 World 对象。但是当我将参数更改为 const World& 时,我得到了另一个错误。 ShadeRec.cpp:在构造函数“ShadeRec::ShadeRec(const World&)”中:ShadeRec.cpp:7:错误:从“const World”类型的表达式中对“World&”类型的引用的初始化无效
【解决方案4】:

假设您可以从World 构造一个ShadeRec 而无需修改传入的World,您需要这样的ShadeRec 构造函数:

 ShadeRec(const World& world);

【讨论】: