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 ++では、キャストによってポインタのアドレスが変更されることがよくあります。Base *にキャストする前ににキャストする必要があります。そうしないとvoid *、動作が未定義になります。(Void *への/からのキャストは問題ありませんが、キャストバックする場合は、両端でまったく同じタイプである必要があります)

于 2010-09-17T16:32:22.160 に答える
2

dynamic_cast<void*>どちらが最も派生したオブジェクトへのポインタを取得するかを考えていると思います。

void*ポリモーフィックタイプのオブジェクトを削除するためだけに実行する必要はありません。オブジェクトへのポインタであれ、オブジェクトへのポインタであれdelete、あなたが持っているポインタをすべて取得してください。メソッドは必要ありません。Base*MoreDerivedMoreDerived*Kill

于 2010-09-17T17:13:40.053 に答える
2

KillObjectが常にを削除する場合Base *、なぜそれがかかるのvoid *ですか?に変更ptrBase *、キャストを取り除きます。次に、渡されたものが、、、、またはであるBase *場合、それは機能します。Derived *MoreDerived *

于 2010-09-17T16:17:13.050 に答える
2

ポインターをキャストすることによりvoid *、継承ツリーを上下に変換する方法に関するコンパイラーの知識が失われます。同じオブジェクトへの 2 つのポインタが必ずしも同じ値を持つとは限らないため、これは多重継承がある場合に特に問題になります。

そうしないでください。

于 2010-09-17T16:21:23.717 に答える
2

static_cast を void* にすると、標準は、元のポインター型への static_cast が正しく機能することのみを保証します。前述のように、dynamic_cast が必要か、最初に Base* に static_cast してから 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()

Re Potatoswatter:「より効果的なC ++」で彼らが使用について言及しdynamic_cast< void* >たと思いますが、私はその文を再び見つけることができませんでした。これを試して、結果をお知らせします。

再度、感謝します

于 2010-09-18T10:12:14.500 に答える