2011-01-25 7 views
6

と呼ばれている(これらはフェッチとメモリプールからとにメモリを戻します)。私に不快感を与えているのは、私がオーバーロードしているクラスに、削除オーバーロードされた関数getが呼び出される前に、デストラクターが呼び出されているということです。どうすればこれをやめることができますか?停止デストラクタが、私は新しいのオーバーロードと削除していた上のクラスを持っている

class Message 
{ 
    ~Message() { ... } 

    void* operator new(std::size_t sz) { ... } 
    void operator delete(void* ptr) { ... } 
}; 

EDIT:クラスのメンバーが破壊されますが、メモリがデストラクタによって解放されないという考えで正しい

アム。 delete関数はこの責任を持ちます。その場合、メモリの割り当てを解除することはできますか?

結果: ペニーは、メモリと建設/破壊の割り当て/割り当て解除は別々の項目であると判断しました。空のデストラクタがあり、新しい/削除がオーバーロードされました。

+2

私はそれがなぜイライラするのか分かりません。この点でC++は非常に論理的です。あなたが何かをする必要がなければ、空のデストラクタを残す。 –

答えて

6

破壊および割り当て解除は、2つの直交するものであり、一方が他方を阻害してはなりません。スタック上に作成されたクラスのインスタンスではどうしますか?リソースをクリーンアップしないでください。あなたはRAIIという非常に便利な概念を打ち破ろうとしています。あなたは(a)の特定のプールからメモリをつかみ、(b)のデストラクタが、1つのオプションと呼ばれていたときに制御が心配な場合

4

私はあなたが呼ばれてからデストラクタを防ぐことができるとは思わない、と私はあなたがしたいと思う理由はわかりません。メモリが解放される前に、オブジェクトを破壊する必要があります。スーパークラスがいくつかのリソースを割り当てた場合、そのデストラクタはオブジェクトのメモリが解放される前に解放する必要があります。あなたの編集後

編集:はい、デストラクタは、彼らが割り当てられた何かをクリーンアップするが、オブジェクトのメモリを解放しません。あなたが書いている方法はdeleteです。

ところで、素敵な名前。 :-)

3

placement newです:

void* raw = allocate(sizeof(Foo)); // line 1 
Foo* p = new(raw) Foo();   // line 2 

p->~Foo(); // explicitely call destructor 

(コードはCへのリンクの上から撮影++ FAQ)

0

あなたの質問に答えると、新しい/削除をオーバーロードするかどうかに関係なく、コンストラクタとデストラクタが呼び出されます。あなたはそれがメモリプールでオブジェクトを使用するための良い解決策だかどうか、聞いていなかった質問に答える

は、答えは一般的である - 「ノー」。あなたが望むのはクラスで、メモリプールを使ってアロケータクラスを操作します。これは、より多くの柔軟性を可能にし、通常はクラスを1つだけ持つのではなく、メモリプールに入れられる多くのものなので、すべての新規/削除関数の大規模なオーバーロードを望んでいません。また、いくつかの割り当てスキーム(したがってアロケータ)を持つことは珍しいことではありませんが、新しい/削除を一度だけオーバーロードすることができます。

+0

質問に答える:C++でデストラクタを呼び出さないようにするには?これは、割り当てのために新しい配置を使用する場合にのみ行うことができます。その場合は、プログラマとして、デストラクタを手動で呼び出す必要があります(Dougは次のように言っています:p->〜Foo :: Foo() ;)。これはプログラマがデストラクタを手動で呼び出す必要がある言語の唯一のインスタンスです。 – Viren

関連する問題