2

やあみんな私は簡単なテストを書きました。delete を呼び出して deleteMe を呼び出してから、それ自体を削除します。これの目的は、lib によって割り当てられた obj を正常に削除できるようにすることです。(crtまたはw / eによるクラッシュは望んでいません)。

これを削除すると、スタックオーバーフローが発生します。それがなければ、msvc は 4 バイトがリークしたと言います。test を呼び出さないと 0 がリークします。再帰の問題がある場合はどうすれば削除できますか? -編集-これをより明確にするために。crtが原因で、LIBがプログラムの代わりにdelete(したがってdeleteMe)を呼び出すようにしたい

class B
{
public:
    virtual void deleteMe()=0;
    static void operator delete (void* p) { ((B*)p)->deleteMe(); }
};

class D : public B
{
public:
    void deleteMe()      {
        delete this;
    }
};

int test()
{
    B *p = new D;
    delete p;
    return 0;
}
4

3 に答える 3

1

再帰は、再度呼び出す B を呼び出す の呼び出しdeleteMeによるものです。特に「外部」オブジェクトを処理する場合は、通常はオーバーロードしますが、オーバーロードしても問題ありませんが、 custom 内から実際のクリーンアップルーチンを呼び出す必要があります。deleteoperator deletedeleteMeoperator deleteoperator newdelete

一般に、オーバーロードされたoperator deleteは と一致する必要がありoperator newます。あなたの場合:

B *p = new D;

herepは global で割り当てられているnewため、 global で解放する必要がありますdelete。そう:

class D : public B
{
public:
    void deleteMe()      {
        ::delete this;
    }
};
于 2009-01-14T14:10:44.127 に答える
1

削除をオーバーライドしないでください。特に、delete を呼び出す関数には当てはまりません。必要なメモリの解放 (この例では何もする必要はありません) は、デストラクタで行う必要があります。

于 2009-01-14T13:55:20.273 に答える
0

おそらく、クライアントが呼び出すことが期待される Destroy() メソッドを持つ方がよいでしょう...これにより、ライブラリがヒープの違いから保護されます。

于 2009-01-14T14:08:21.183 に答える