3

私はレビューのために仮想デストラクタを使って少し実験をしていました.

I クラス階層 ABCD を定義します。D は C を継承し、C は B を継承し、B は A を継承し、A はベースです。

2 つの実験を実行しました。

最初の実験 -

A には仮想デストラクタがあります。

B には非仮想デストラクタがあります

Cには仮想デストラクタがあります

D には非仮想デストラクタがあります

//----------------------------

タイプ D のヒープに 4 つのオブジェクトを割り当てます - 最初の 3 つで A*、B*、C* のポインターをポイントします - 完全性のために 4 番目を D* として残します。4 つのポインターをすべて削除します。

予想どおり、4 つのインスタンスすべてで、完全なデストラクタ チェーンが D から A まで逆の順序で実行され、すべてのメモリが解放されます。

第二の実験 -

A には非仮想デストラクタがあります ** A を非仮想に変更しました

B には非仮想デストラクタがあります

Cには仮想デストラクタがあります

D には非仮想ディストラクタがあります

タイプ D のヒープに 4 つのオブジェクトを割り当てます - 最初の 3 つで A*、B*、および C* のポインターをポイントします - 完全性のために 4 番目を D* として残します。

C* および D* ポインタの削除: 完全なデストラクタ チェーンが D から A まで逆の順序で実行され、すべてのメモリが解放されます。

B* の削除: B の後に A デストラクタが実行されます (リーク)

A* の削除: デストラクタのみが実行されます (リーク)

誰がこれがなぜなのか説明できますか?

実験 2 で D 型のオブジェクトが割り当てられると、その直接の基本クラス (C) に仮想デストラクタがあります。これは、コンパイラに Vptr でそれを追跡し、メモリの型を知るように指示しませんか? 参照に関係なく?

ありがとうマイク

4

4 に答える 4

6

実験 2 で D 型のオブジェクトが割り当てられると、その直接の基本クラス (C) に仮想デストラクタがあります。これはコンパイラに Vptr でそれを追跡し、メモリ型を知るように指示しませんか? 参照に関係なく?

いいえ。

2 番目のテスト ケースでは、 vptrs/vtables がAありBません。(たとえそうしたとしても、非仮想メンバー関数は動的ではなく静的に解決されます。)

別の言い方をすれば、基底クラスは派生クラスから情報 (関数が仮想かどうかなど) を "継承" しません。

于 2012-06-15T16:58:29.617 に答える