2012-01-03 26 views
0

現在のセットアップで発生する結果を100%確信しているわけではありません。継承と仮想メンバ関数

これは愚かな質問かもしれませんが、私には同じような例はありません。私はgetSomeParticularInfoを呼び出す場合

:ここ

は、サンプルコード

Class A { 

    public: 
    virtual Steer* getSomeParticularInfo(){ return m_steer; } 

    private: 
    Steer* m_steer: 
} 


Class B: A { 

    public: 
    virtual Steer* getSomeParticularInfo(){ return m_steer; } 

    private: 
    Steer* m_steer: 
} 

Class C: B { 

    public: 
    //Does not have its own getSomeParticularInfo() member function 

    private: 
    Steer* m_steer: 
} 

は私の質問です。クラスBから来たのは、それが最新の派生クラスであるか、ベースクラスから来たものなのか?

//Inside Class C constructor 
C::C(){ 
    m_steer = getSomeParticularInfo(); 
} 
+2

。 – dasblinkenlight

+2

しかし、[このコードの臭い](http://en.wikipedia.org/wiki/Code_smell)を教えてください。 –

答えて

5

これを理解するには、ここでコンストラクタの順序を理解する必要があります。 C::C()の本体が実行される前に、基本型のコンストラクタが実行されます。この場合B::B()。これは再帰的なプロセスなので、最後にAB、およびCのコンストラクタが順番に実行されます。

C++での型のコンストラクタは、仮想メソッドテーブルを、それが定義する仮想メソッド/オーバーライドのバージョンを指すように変更します。したがって

  • A::A()C::C()Aのコンストラクタの両方を実行しており、Bがで実行された時点でB::getSomeParticularInfo

からgetSomeParticularInfoのエントリを設定しますA::getSomeParticularInfo

  • B::B()からgetSomeParticularInfoのエントリを設定しますその順序。したがって、getSomeParticularInfoへの呼び出しは、B::getSomeParticularInfo

    に解決されます。一般的には、コンストラクタで仮想メソッドを使用しないでください。一般的に混乱の可能性があるため、悪い練習をしています。

  • 0

    はい。 getSomeParticularInfo()をCから呼び出すと、Bからm_steerになります。

    上記のスニペットの唯一の問題は、コンストラクタから仮想メソッドを呼び出さないことです。

    1

    コンパイルように、それは故意にA::m_steerを無視し、C::m_steerの存在を認識しませんB::getSomeParticularInfo()

    、その関数を呼び出します。

    1

    明示的等からそれを呼び出すしない限り、それはBからm_steer次のようになります。それは 'B'クラスから来る

    A::getSomeParticularInfo()