2012-02-26 20 views
-1

I持って、次のクラス:仮想継承と同じ名前のメンバー

class Base 
{ 
public: 
    Base() { x = 3; } 
    int x; 
    virtual void foo() {}; 
}; 

class Med1 : public virtual Base 
{ 
public: 
    int x; 
    Med1() { x = 4; } 
    virtual void foo() {}; 
}; 

class Med2 : public virtual Base 
{ 
public: 
    virtual void goo() {}; 
    virtual void foo() {}; 
}; 

class Der : public Med1, public Med2 
{ 
public: 
    Der() {} 
    virtual void foo() {}; 
    virtual void goo() {}; 
}; 

し、次のコード:

Base* d = new Der; 
d->foo(); 
cout << d->x; 

出力:なぜそれは

3 

のですか?コンストラクタBaseの後にMed1コンストラクタが呼び出されます。私はそれがBase::xではなくであると推測していますが、Der::xBase::xと同じで、Med1::xと同じではありません。なぜあいまいさがないのですか?

答えて

1

dに移行Baseへのポインタであるので、d->xBase::xを明確に指します。 Derへのポインタであれば、あいまいさがあります。

+0

ハ!理にかなって、なぜ私はそれを逃したのか分からない。しかし、私はコードを変更しましたが、あいまいさはありません。 'Der'へのポインタがあれば' 4'を表示します。 'Med1'は' Base :: x'を隠しています。 –

-1

変数xは仮想ではないので、コンパイラはその頭を傷つけ、あなたにハングアップする必要があります。したがって、Base->x

+0

もちろん、C++ではデータメンバーを仮想にすることはできません。 (私の推測では、この答えは変数が仮想である可能性を暗示していたという事実に関するdownvoteだと思います...)ポイントは、 'Med1 :: x'は' Base :: x'をオーバーライドしません。仮想**関数**宣言は、他の仮想関数宣言を上書きすることができます。 – curiousguy

0

ベースへのポインタなので、ベースはベースになります。 コンストラクタの順序はスーパークラスであり、派生クラスです。したがって、Baseクラスのコンストラクタは、最初にDer、その後に呼び出されます。

+0

答えの最初の部分はマイクのものと同じです。私がすでに質問に述べた第二の部分... –

関連する問題