我跟随了一些示例代码,但是我收到了一条错误消息,我不知道如何正确修复。 我收到错误传递* this作为参考。这是相关代码:
//ShadeRec.h
class World;
class ShadeRec
{
public:
World& w;
ShadeRec(World& wr)
}
ShadeRec::ShadeRec(World& wr) : w(wr) {}
//World.h
#include "ShadeRec.h"
#include "Ray.h"
class World
{
public:
World();
ShadeRec hit_bare_bones_objects(const Ray& ray) const;
}
ShadeRec World::hit_bare_bones_objects(const Ray& ray) const
{
ShadeRec sr(*this);
//Do stuff with sr
return sr;
}
错误发生在hit_bare_bones_objects中,我声明ShadeRec sr(* this);错误是:
1>错误C2664:' ShadeRec :: ShadeRec(const ShadeRec&)' :无法转换来自' const World'来到世界 &安培;'
1 GT;转换失去限定符
这样做的正确方法是什么?
答案 0 :(得分:3)
"这样做的正确方法是什么?"
您需要使用const
引用参数
ShadeRec(const World& wr);
// ^^^^^
或宣布您的
ShadeRec hit_bare_bones_objects(const Ray& ray); // <<< no const
World
类非const
中的
成员函数。
正确的方式取决于//Do stuff with sr
包括在非const
World
实例上运行。
声明为const
的类函数成员无论如何只能访问const
this
指针,该指针只能依次取消引用为const
引用。
第三个选项是在与另一个类的接口交互时使用const_cast<>
。这不一定是推荐的,你应该真的知道你在做什么。它具有类似的危险等级,例如使用reinterpret_cast<>
1 :
ShadeRec World::hit_bare_bones_objects(const Ray& ray) const {
ShadeRec sr(*const_cast<World*>(this));
// ^^^^^^^^^^^^^^^^^^^ ^
//Do stuff with sr
return sr;
}
1)我偶尔使用const_cast<>
,当我被其他API(我无法更改或修补)烦恼时,不要#&# 39; t const
correctness正确。我仍然不希望让他们将错误传播到我的代码中(只要我确定这样做)。
答案 1 :(得分:1)
ShadeRec::ShadeRec
说“你给我的世界wr
是非常数的;不保证它会保持不变”。 ShadeRec sr(*this);
说“这是一个不变的世界,即不得改变”。这是一场冲突。要解决此问题,请将ShadeRec(World& wr)
(和World& w
)设为常数,或使World::hit_bare_bones_objects
为非常数。
答案 2 :(得分:0)
创建ShadeRec
构造函数const的参数声明:
ShadeRec::ShadeRec( const World& wr)
定义hit_bare_bones_objects
时,它被标记为const
,这意味着不允许该函数更改this
的状态。如果您在*this
的构造函数中通过非const引用传递ShadeRec
,则可能允许ShadeRec
违反该const声明。因此,您通过const引用。
您也可以从const
中移除hit_bare_bones_objects
,然后您可以保留ShadeRec
构造函数。
有意义吗?
答案 3 :(得分:0)
在你的方法中:
ShadeRec World::hit_bare_bones_objects(const Ray& ray) const
您告诉编译器您不会修改World
中的任何对象。
您需要将*this
作为常量参考传递。
答案 4 :(得分:0)
您收到此错误是因为您在*this
方法中传递了const
。所以这里也是const,并且只能在const上下文中使用。
所以,如果你想把这个方法保持为const那么你应该:make:
ShadeRec::ShadeRec(const World& wr) : w(wr) {}
^^^^^
但ShadeRec中的World& w;
也应该更改为const World& w;
,这可能不是您想要的。