Arantium Maestum

プログラミング、囲碁、読書の話題

Effective C++勉強メモ: Item 9 virtual関数をコンストラクタ・デストラクタから呼ぶな

C++のコンストラクタは、まず最下層のベースクラスのものが呼び出されて、順次初期化されていって最終的に実際に作成されるオブジェクトのコンストラクタの処理が走る、という流れになる。

class A {
  public:
    A();
    virtual void init();
};

A::A() {
  init();
}

class B : public A {
  public:
    void init();
};

class C : public B {
  public:
    void init();
};

int main() {
  C c;
  return 0;
}

などといったコードの場合、Cクラスのオブジェクトインスタンスを初期化しているのにも関わらず、呼び出されているinitはAクラスのもののみとなる。

しかし、個人的にはこれは「そりゃそうだ」としか思わないのだが・・・

逆にC::C() { init();}という定義があれば、その時点でCクラスのinitが使われる。「コンストラクタ内でvirtual関数を使ってはダメ」ではなく、「ベースクラスのコンストラクタで使うvirtual関数はそのベースクラスのものだと忘れるべきではない(正しいクラスのコンストラクタで呼ぶようにしよう)」というだけでは?あまり腑に落ちない項目である。