1

次の階層がある場合:

  • クラス F には、型のメンバー オブジェクトが含まれます (クラス E およびクラス D、この順序で宣言されます)。
  • クラス F は具体的なクラス クラス C を継承します
  • クラス C は、抽象/純粋仮想クラス クラス B を継承します
  • クラス B は具体的なクラス クラス A を継承します

クラス F 型のオブジェクトのデストラクタが呼び出されると、次のことが次の順序で行われます。

  1. クラス F (最も派生した) デストラクタが呼び出され、終了します
  2. クラス D (メンバー オブジェクト 2) のデストラクタが呼び出されて終了する
  3. クラス E (メンバー オブジェクト 1) のデストラクタが呼び出されて終了する
  4. クラス C (F のベース) デストラクタが呼び出されて終了する
  5. クラスA(CのベースであるBのベース)デストラクタが呼び出され、終了します
  6. クラス B (仮想、C のベース) デストラクタが呼び出され、終了します

これは正しいです?つまり、基本的に終わりに向かって、C は仮想 B を継承し、仮想 B は A を継承しますが、C は破壊され、次に A、次に仮想 B になりますか?

編集: C++ FAQ は言う:

「仮想基本クラスは特別です。それらのデストラクタは、最も派生したクラスのコンストラクタの最後で呼び出されます」

私が理解しようとしているのはどれですか?

4

2 に答える 2

3

デストラクタは、コンストラクタとは逆の順序で実行されます。それはあなたが知る必要があるほとんどすべてです。

更新: 仮想基地にも当てはまります。仮想ベースは、他のベース クラスよりも前に構築されることに注意してください。

于 2013-02-28T20:46:09.113 に答える
3

おそらく、デストラクタ呼び出しの順序をアルゴリズムとして表現するのが最も簡単でしょう。

破壊

  1. プログラマーがデストラクタの本体に書いたことは何でも実行します。F::~F() { do_this; do_that; }
  2. メンバーを破棄(デストラクタを呼び出す)
  3. 非仮想基本クラスを破棄(デストラクタを呼び出す)
  4. 仮想基本クラスを破棄(デストラクタを呼び出す)

このアルゴリズムは言語 (またはコンパイラ) によって実行されるため、プログラマは最初のステップのみを制御できます。

注: 以降の各ステップは再帰的です。

デストラクタ呼び出しの順序は、コンストラクタ呼び出しの逆順です (構築順序は直感的に理解できるので知っておくとよいでしょう)。仮想基地の破壊の順序は次のように指定されます。

基底クラスのグラフの深さ優先の左から右への走査

幸いなことに、これは 1 つしかないので必要ありません。

于 2013-02-28T21:35:47.947 に答える