1

我有以下类层次结构:

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*),但应用程序仍然崩溃......

4

6 回答 6

4

在 C++ 中,强制转换通常会导致指针地址发生变化。您需要在转换为 aBase *之前转换为void *,否则您有未定义的行为。(向/从 Void * 施放是可以的,但是当施放回来时,它的两端必须是完全相同的类型)

于 2010-09-17T16:32:22.160 回答
2

如果 KillObject 总是删除 a Base *,为什么它需要 a void *?改变ptr成为Base *并摆脱演员阵容。然后,如果传入的东西是 a Base *、 aDerived *或 a MoreDerived *,它将起作用。

于 2010-09-17T16:17:13.050 回答
2

通过将指针转换为void *您正在删除编译器关于如何上下转换继承树的知识。当存在多重继承时,这尤其是一个问题,因为指向同一对象的两个指针不一定具有相同的值!

不要那样做。

于 2010-09-17T16:21:23.717 回答
2

我认为您正在考虑dynamic_cast<void*>which 获得指向最派生对象的指针。

你不需要经历一个void*只是为了删除一个多态类型的对象。只需获取您拥有的任何指针,无论是delete指向Base*对象MoreDerived还是MoreDerived*. 不需要Kill方法。

于 2010-09-17T17:13:40.053 回答
2

如果您将 static_cast 转换为 void*,则标准仅保证将 static_cast 转换为原始指针类型将正常工作。如前所述,您要么需要 dynamic_cast,要么需要先将 static_cast 转换为 Base*,然后再转换为 void*。从 void* 到 Base* 的 static_cast 应该可以正常工作。

于 2010-09-17T20:48:36.913 回答
0

非常感谢您的所有回复。

只是为了澄清情况并详细说明代码,我在 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);

Re Billy O'Neal:我想通过这样做Base* ptrToBase = obj;,我已经做了一个 static_cast 到Base*??

Re Mark Ransom:通过打印出指针并执行删除操作,我看到指针一直具有相同的地址,并且它在~MoreDerived().

回复 Potatoswatter:我认为他们在“更有效的 C++”中提到了 using dynamic_cast< void* >,但我再也找不到那句话了。我会试一试,让你知道结果。

再次感谢

于 2010-09-18T10:12:14.500 回答