AFAIK、仮想継承は菱形継承問題を解決しますが、仮想を使用して基本クラスから単純に継承するとどうなりますか?virtual
ここで使用することとの違いは何ですか?
class A
{
/* ... */
};
class B : virtual public A
{
/* ... */
};
AFAIK、仮想継承は菱形継承問題を解決しますが、仮想を使用して基本クラスから単純に継承するとどうなりますか?virtual
ここで使用することとの違いは何ですか?
class A
{
/* ... */
};
class B : virtual public A
{
/* ... */
};
いくつかの違いがあります。オブジェクトのレイアウトは異なります (仮想継承の場合、派生したサブオブジェクトのベースへの追加の隠しポインターがあります)、サブオブジェクトの初期化は異なります (から派生する型は、初期化でコンストラクターを直接B
呼び出す必要があります)A
リスト)。B
メンバー (データまたは関数)を参照するメンバー関数内のコードにはA
、(前述のポインターを介した) 追加の間接化が必要であり、場合によってはその他の相違点もあります。
仮想継承は複雑な問題であり、別の質問から少しずつ取得して理解するよりも、前の質問への回答で提供されているリンクをもっと読む必要があります。
ヒント: コンパイラによる仮想継承の処理方法の詳細を理解したい場合は、オブジェクトのメモリ レイアウトに注目する必要があります。仮想的に派生するクラスごとに追加のポインターが必要な理由を理解したら、あとは簡単です。