1. ホーム
  2. c++

[解決済み] 仮想継承でDefaultコンストラクタが呼ばれるのはなぜですか?

2023-06-03 14:15:25

疑問点

以下のコードにおいて、なぜ daughter 型のオブジェクトをインスタンス化すると、デフォルトの grandmother() のコンストラクタが呼び出されます?

のどちらかが grandmother(int) コンストラクタを呼び出す必要があります (私の mother のコンストラクタを呼び出すか、仮想継承のためにこのコードは全くコンパイルされないはずです。

ここではコンパイラは無言で grandmother のデフォルトコンストラクタを呼び出しています。

#include <iostream>

class grandmother {
public:
    grandmother() {
        std::cout << "grandmother (default)" << std::endl;
    }
    grandmother(int attr) {
        std::cout << "grandmother: " << attr << std::endl;
    }
};

class mother: virtual public grandmother {
public:
    mother(int attr) : grandmother(attr) {
        std::cout << "mother: " << attr << std::endl;
    }
};

class daughter: virtual public mother {
public:
    daughter(int attr) : mother(attr) {
        std::cout << "daughter: " << attr << std::endl;
    }
};

int main() {
  daughter x(0);
}

どのように解決するのですか?

仮想継承を使用する場合、仮想基底クラスのコンストラクタは、最も派生したクラスのコンストラクタから直接呼び出されます。この場合 daughter のコンストラクタは直接 grandmother コンストラクタを呼び出します。

を明示的に呼び出したわけではないので grandmother を明示的に呼んでいないので、デフォルトのコンストラクタが呼び出されます。正しいコンストラクタを呼び出すには、次のように変更します。

daugther(int attr) : grandmother(attr), mother(attr) { ... }

参照 このFAQのエントリ .