仮想継承を使用して、通常のダイヤモンドの問題を通常の方法で「解決」しようとすると、奇妙な問題が発生しました。
A
/ \* both virtual
B C
\ /
D
ただし、基本クラス A にはデフォルトのコンストラクターがないため、D から手動で呼び出す必要がありました。ただし、このダイヤモンドにクラス E を C 継承として追加しようとすると、
A
/ \* both virtual
B C
\ / \
D E
E コンストラクターで A のコンストラクターを手動で呼び出す必要があります。つまり、多重継承もダイヤモンド ACE もありませんが、C は E から A を作成するものではありません。
class A
{public:
A (int _N): N(_N) {};
void show()
{cout<<"A"<<N;}
protected:
int N;
};
class B: public virtual A
{ public:
B(int n): A(2*n) {};
void show()
{ cout<<"B"<<N;}
};
class C: public virtual A
{ public:
C(int n): A(3*n) {};
void show()
{ cout<<"C"<<N;}
};
class D: public B,C
{ public:
D(): B(1), C(2), A(3) {};
void show()
{ cout<<"D"<<N;}
};
class E: public virtual C
{ public:
E(): C(1) {};
void show()
{ cout<<"E"<<N;}
};
int main()
{D d; // OK
A *a = &d;
a->show();
E e; // NOT OK, no function A::A() to call in E::E()
A *a2 = &e;
a2->show();
return 0;
}
E から A のコンストラクターを呼び出さずにこの問題を解決することは可能ですか? 適切に行うにはCが必要です:-)。
または、ダイヤモンドの問題をまったく解決しようとしないことは可能ですか?
A A
| | no virtual at all
B C
\ / \
D E
それでも、Aの2つのインスタンスでクラスDのオブジェクトを宣言しようとしますが、毎回Dから照合するときにコンパイラにCのAを使用するように指示しますか? 追加しようとすると
using C::A
D の宣言では、明確な基数 A のエラーが発生します。