3

C++ のゴールデン ルールの 1 つは、インスタンスの有効期間は、コンストラクターが正常に完了したときに始まり、デストラクターが開始されたときに終了するというものです。

このルールから、コンストラクターで仮想メソッドを呼び出すことはお勧めできません。派生インスタンスの可能性が無効であり、未定義の動作につながる可能性があるためです。

C++ FAQ 20.8で言及されている Virtual Constructor Idiomは、反対のことを示しているようです。

私の質問は:

  • コンストラクタとデストラクタからの呼び出しに関連するオブジェクトの寿命を定義するための標準の正確な定義は何ですか?
  • さらに、いわゆる「仮想コンストラクタ Idom」は有効ですか?
4

2 に答える 2

7

2 つの別個の (漠然と関連している場合) を混同していると思います。

  1. here で説明されている理由により、コンストラクターから仮想関数を (直接的または間接的に) 呼び出すべきではないことはよく知られています。
  2. FAQ が話しているのは、仮想関数からコンストラクターを呼び出すことです。ある意味、1とは真逆です。アイデアは、既存のオブジェクトの動的な型に基づいてコンストラクター (つまり、クラス) を選択することです。
于 2010-12-11T08:08:03.790 に答える
2

オブジェクトは、コンストラクターの開始時にコンストラクターが属するクラスの型として存在します。オブジェクトは一貫性のない状態にある可能性があります (現在、実行はオブジェクトのメソッドの 1 つの内部にあるため、これは問題ありません)。つまり、実際には Base を継承する Derived 型のオブジェクトは、Base コンストラクターでは Base として扱われます。thisin anyは、指すオブジェクトの実際のタイプに関係なく、Base::Base()として扱われます。仮想メソッドの呼び出しは問題ありません。コンストラクターでは、オブジェクトの実際の型ではなく、コンストラクターのクラスの仮想メソッドが呼び出されます。Base *this

最初の質問は、「派生クラスのコピー コンストラクターの初期化リストの基本クラス」で説明されています。簡単な答えは、C++03 の § 12.7 2-3 でカバーされているということです。

仮想コンストラクターのイディオムは完全に有効です。

于 2010-12-11T08:01:20.230 に答える