我有一个析构函数,用于检查是否已经分配了指针,如果有,则将其删除:
ShadeRec::~ShadeRec(){
cout << "before deleting ShadeRec" << endl;
if(material){
cout << material << endl;
delete material;
material = NULL;
}
cout << "after deleting ShadeRec" << endl;
}
第一个指针经过罚款,然后第二个指针给我错误。
我已经使用cout
进行了检查,并且指针内部有一些内容,因为它进入了if语句,这是有道理的...所以为什么它会给我错误?
构造
ShadeRec::ShadeRec(World& world)
: hit(false),
material(NULL),
hitPoint(),
localHitPoint(),
normal(),
ray(),
depth(0),
colour(0),
t(0.0),
w(world)
{}
ShadeRec::ShadeRec(const ShadeRec& sr)
: hit(sr.hit),
material(sr.material),
hitPoint(sr.hitPoint),
localHitPoint(sr.localHitPoint),
normal(sr.normal),
ray(sr.ray),
depth(sr.depth),
colour(sr.colour),
t(sr.t),
w(sr.w)
{}
材料运营商=
Material&
Material::operator= (const Material& rhs) {
if (this == &rhs)
return (*this);
return (*this);
}
Matte是Material的孩子:
Matte* matte1 = new Matte;
这两个:
Matte& operator= (const Matte& rhs);
virtual Material* clone(void) const;
答案 0 :(得分:4)
最有可能的是:
material
是ShadeRec
ShadeRec
的构造函数接受/设置指针ShadeRec
个实例,可能会将其复制为参数或返回值。NULL
要使其可见,还要在您的dtor中打印this
,您会看到它是ShadeRec
的另一个实例。
编辑后:这就是这一行:
material(sr.material),
应该创建对象的副本,而不仅仅是复制普通指针。另一个选项,通常更可取的是使用std::shared_ptr
(如果您可以使用C ++ 11,否则请查看boost::shared_ptr
),但要注意ShadeRec
的副本将共享相同的内容材料实例。
鉴于您目前所显示的内容,请使用
替换copy-ctor中的上述行material(sr.material->clone()),
看看它是否有效。
答案 1 :(得分:2)
<强>问题强>
您没有定义深层复制构造函数。当您复制一个ShadeRec
对象时,指针会被复制,因为它们会导致两个类之间发生冲突。
使用时如:
ShadeRec a;
ShadeRec b(a);
两个实例包含相同的地址,这意味着当第一个实例正确释放其指针时,第二个仍然必须释放其指针(已经被另一个释放)。
解决方案示例
这是一个正确的深拷贝构造函数的示例。
考虑material
是指向动态分配的Material
对象的指针,并且Material
类具有正确定义的复制构造函数:
ShadeRec::ShadeRec(const ShadeRec& sr)
: hit(sr.hit),
material(0), // <--- NULL
hitPoint(sr.hitPoint),
localHitPoint(sr.localHitPoint),
normal(sr.normal),
ray(sr.ray),
depth(sr.depth),
colour(sr.colour),
t(sr.t),
w(sr.w)
{
if (sr.material)
material = new Material(*(sr.material));
}
以下是如何编写正确的赋值运算符的示例:
Material&
Material::operator= (const Material& rhs) {
if (this != &rhs) {
if (material)
delete material;
// make member per member assignments here
material = new Material(*(rhs.material));
}
return (*this);
}
更多强>
如果可以的话,你应该使用智能指针,从C ++ 11开始,它在STL上实现为std::shared_ptr
,或者在C ++ 11之前,在boost库中可用{{1} }}