2012-04-18 4 views
1

deleteを使わずに、クラスの種類を知らなくてもオブジェクトのデストラクタを呼び出すことはできますか?私はアロケータ(楽しい/練習用)に取り組んでいるので、コンストラクタにオブジェクトを構築するのにmalloc/placement newを使用していますが、オブジェクトを破棄するときには、タイプを知っている。それが不可能な場合は、どうしてですか?唯一の方法は、サンプルコード(コメントアウトされている)に表示される方法ですか?型を知らなくてもデストラクタを呼び出すことはできますか?

#include <stdio.h> 
#include <new> 

void* SomeAllocationFunction(size_t size) { 
    return malloc(size); 
} 

class SomeClass{ 
public: 
    SomeClass() { 
     printf("Constructed\n"); 
    } 

    ~SomeClass() { 
     printf("Destructed\n"); 
    } 
}; 

int main(void){ 
    void* mem = SomeAllocationFunction(sizeof(SomeClass)); 
    SomeClass* t = new(mem)SomeClass; 

    free(t); 
    //t->~SomeClass(); // This will call the destructor, is it possible to do this without knowing the class? 

    return 0; 
} 

(私はちょうど削除を呼び出すことができます知っているが、一瞬のためにそれを無視してください。)

+0

クラス固有を呼び出すための唯一の方法(vtblのコンセプトと同様に)実行時にルックアップを実行するために使用できる、すべてのインスタンスに組み込まれたクラス固有の情報があるかどうかです。それは一般的にそうではありません。 –

+3

't->〜SomeClass()'を呼んでしまうと、間違いなく* * 'free(t)'の前に*したいと思うでしょう。 –

+0

@Greg Hewgill:それはちょうどコメントされたコードだった、私は注文と混同するつもりはなかった。 – mmurphy

答えて

2

いいえ、タイプを知ることなく(または仮想デストラクタを持つオブジェクトの基本タイプの1つを知っていなければ)不可能です。

通常、カスタムアロケータはオブジェクトの作成も破棄もしませんが、配置先の新規または直接デストラクタコールを実行するアロケータの周りにテンプレートラッパーを作成するものもあります。

(技術的には、あなたはすべての割り当てとタイプのデストラクタを呼び出して終了関数ポインタを関連付けることができます。しかし、それはかなり大ざっぱだ、と私はそれをお勧めしません。)

+0

私はラッパーが直接デストラクタ呼び出しの型を知っている必要があると思いますか? (マクロのように) – mmurphy

+0

それは破壊されているオブジェクトの型にテンプレート化されます。しかし、型が推論される可能性があるので、 'free()'呼び出しと全く異なる必要はありません。 –

2

コンパイラが知らないのでいいえ、あなたは、クラスを知らなくても、デストラクタを呼び出すことはできませんどのデストラクタが呼び出すか。あなたは、どちらかの可能性:代わりにボイドポインタの

  • すべてのオブジェクトが仮想デストラクタを持っているいくつかの基本オブジェクトから継承させると、そのベースオブジェクトのポインタを使用
  • テンプレート
  • を利用するには、アロケータそのものではないを持っています
2

型なしで、型なしのメモリ上でデストラクタを呼び出すことは、コンストラクタを呼び出すよりも不可能です。コンストラクタとデストラクタはどちらもオブジェクトの一部であり、コンパイラは何を呼び出すべきかを知るために型が必要です。

関連する問題