7

この回答では、ライアンは仮想デストラクタを直接呼び出します。VS2010 でコードをテストしたところ、すべてのデストラクタが正しく呼び出されました (ロギング ステートメントでテスト済み)。そうすることは実際に有効ですか?このようなアプローチの問題、欠陥、または良い点は何ですか?

reset少なくともデストラクタでクリーンアップする必要があるため、仮想関数をオーバーライドしなくても、実際の型を実際に強制的にリセットする方法としか考えられません。

また、デストラクタの呼び出しはどのような副作用をもたらすのでしょうか? そのようなデストラクタ呼び出しの後にオブジェクトを使用するのは未定義の動作ですか? 呼び出しですぐに再初期化するとどうなりnew (this) MyClass();ますか?

4

3 に答える 3

4

デストラクタを手動で呼び出すことは、仮想かどうかに関係なく、完全に有効です。コンストラクターの呼び出しごとに一度だけ呼び出されるようにするだけです。

Is it undefined behaviour to use the object after such a destructor call? 

はい。

What if one immediatly reinitializes it with a new (this) MyClass(); call?

まだ恐ろしく未定義です。

手動で配置する必要がある場合を除き、オブジェクトを手動で破棄しないでください。たとえば、新しい配置または同等の配置を使用してください。また、そのような破棄されたオブジェクトを再初期化して、UB を回避したい場合は絶対にしないでください。のようなクラスはstd::vector、破棄されたオブジェクトへのアクセスを明示的に UB にし、その場所に新しい要素を作成しても UB のままです。

于 2011-05-17T19:31:20.827 に答える
1

1 つだけの構造を含む有効な使用例:

typedef boost::aligned_storage<
    sizeof(T), boost::alignement_of<T>::value>::type arena_type;
arena_type arena;
T* p = new (&arena) T();
p->~T();
// Don't touch p now

これは、たとえばバリアント型を実装する場合に役立ちます (警告: 読者への演習として残されている例外安全性)。C++0x の無制限共用体は、クラス型に対して同様の用途があります。

クラス型の場合、デストラクタを呼び出さなかった場合、上記は UB になることに注意してください。

于 2011-05-17T19:49:18.167 に答える
0

事前に割り当てられた POD メモリのチャンクの上に新しい配置を呼び出す限り、仮想であろうとなかろうと、任意のデストラクタを呼び出して割り当てを解除することは完全に有効です。

新規および明示的なデアロケータの呼び出しを配置すると、参照された領域でコンストラクタとデストラクタが呼び出されるだけなので、メモリ割り当てはオブジェクトのライフサイクルから効果的に除外されます

于 2011-05-17T19:52:40.170 に答える