[英]C++ Virtual Destructor Crash
我具有以下类层次结构:
class Base
{
public:
virtual ~Base();
};
class Derived : public Base
{
public:
virtual ~Derived();
};
class MoreDerived : public Derived
{
public:
virtual ~MoreDerived();
};
连同物体
Base* base = new Base();
MoreDerived* obj = new MoreDerived(*base);
在代码的一部分中,我需要使用线程删除MoreDerived对象,因此必须首先将其强制转换为void *。 在线程中,我有
void KillObject(void* ptr)
{
delete static_cast<Base*>(ptr);
}
非指针是NULL,并且void* ptr
是 MoreDerived *(或至少是Base *),但是应用程序仍然崩溃...
在C ++中,强制转换通常会导致指针地址的更改。 您需要在强制转换为void *
之前强制转换为Base *
void *
,否则您的行为不确定。 (向/从Void *投射是可以的,但是当被投射回它时,两端必须是完全相同的类型)
如果KillObject总是删除一个Base *
,为什么它需要一个void *
? 将ptr
更改为Base *
并摆脱强制转换。 然后,如果传入的东西是Base *
, Derived *
或MoreDerived *
,它将起作用。
通过将指针强制转换为void *
您将删除编译器有关如何上下转换继承树的知识。 当存在多个继承时,这尤其成问题,因为指向同一对象的两个指针不一定具有相同的值!
不要那样做
如果将static_cast设置为void *,则standard仅保证将static_cast转换为原始指针类型将正常工作。 如前所述,您要么需要dynamic_cast,要么需要先static_cast到Base *,然后再void *。 从void *到Base *的static_cast应该可以正常工作。
我认为您正在考虑dynamic_cast<void*>
,它获取指向最衍生对象的指针。
您无需经过void*
即可删除多态类型的对象。 只需获取您拥有的任何指针并将其delete
,它可以是MoreDerived
对象的Base*
或MoreDerived*
。 不需要Kill
方法。
非常感谢您的所有回复。
只是为了澄清情况并详细说明代码,我在CentOS上使用gcc 4.1.2,他在static_cast中缺少类型是StackOverflow格式错误,并且我有
void KillObject(void* ptr)
{
delete static_cast< Base* >(ptr);
};
// There is a reason for the following as this is a snipet and stuff gets passed around
Base* base = new Base();
MoreDerived* obj = new MoreDerived( * base );
Base* ptrToBase = obj;
// Use ptrToBase in code with no problems
// Delete object, illustrative only - have to cast to void* to pass to API
pthread_run( ... , KillObject , (void*)ptrToBase);
关于Billy O'Neal:我想通过做Base* ptrToBase = obj;
,我已经完成了对Base*
的static_cast?
Re Mark Ransom:通过打印出指针并逐步执行删除操作,我发现指针一直具有相同的地址,并且在~MoreDerived()
处崩溃。
关于Potatoswatter:我认为他们在“更有效的C ++”中提到使用dynamic_cast< void* >
但是我没有再次找到该句子。 我会尝试一下,让您知道结果。
再次感谢
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.