私はこの種のコードを持っています:
class Ref {<undefined>};
Ref refObjectForA, refObjectForB;
class Base
{
public:
Base(const Ref & iRef) : _ref(iRef) {}
virtual ~Base() {}
const Ref & ref;
};
class A: public Base
{
public:
A() : Base(refObjectForA) {}
virtual ~A() {}
};
class B: public A
{
public:
B() : Base(refObjectForB) {} // won't compile: Base is not direct base of B
virtual ~B() {}
};
属性は参照なので、コンストラクタでしか設定できないと思うので、 でコンストラクタを呼び出す必要がありBase
ますB()
。私は 2 つの方法を見つけました: 「フォワード」コンストラクターを提供しますA
(ただし、これは、継承される可能性のあるすべてのクラスにコードを追加することを意味します)。
A(const Ref& iRef): Base(iRef)
または仮想継承を使用します。
class A: public virtual Base
2 番目のオプションでは、実装でより簡単なコードを使用できますが、B
仮想継承を醜いトリックで誤用しているのか、それとも有効なユースケースなのか疑問に思っています。
- この場合、仮想継承を使用できますか?
- いいえの場合、どのような理由で?
私が見つけた「予期しない」動作の 1 つは、仮想継承のためにポインターへのポインターを作成static_cast
できないことです。Base
B
さらに、なぜそれが機能するのかも疑問に思っています(つまり、なぜ a B().ref == refObjectForB
):デフォルトA()
コンストラクターへの暗黙的な呼び出しは、明示的なコンストラクターの後に属性B()
を上書きすると思いますが、仮想継承ではそうではないかもしれません。ref
Base