2012-01-03 109 views
0

我不是100%確定將在我當前的設置中發生的結果。繼承和虛擬成員函數

這可能是一個愚蠢的問題,但我看不到類似的例子。

下面是示例代碼

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: 
} 

我的問題:

如果我打電話getSomeParticularInfo。它會來自B類,因爲它是最近的派生類,還是來自基類?

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

它將來自類'B'。 – dasblinkenlight 2012-01-03 17:18:15

+2

但是讓我告訴你,[這個代碼味道](http://en.wikipedia.org/wiki/Code_smell)。 – 2012-01-03 17:22:16

回答

5

爲了理解這個,你需要在這裏理解構造函數的順序。在執行C::C()的主體之前,將執行基類型的構造函數。在這種情況下,B::B()。這是一個遞歸的過程,所以你最終得到的是構造函數ABC按順序執行。

C++類型的構造函數將更改虛擬方法表以指向它定義的虛擬方法/覆蓋的版本。因此

  • A::A()將設置的getSomeParticularInfoA::getSomeParticularInfo
  • B::B()入口將設置的getSomeParticularInfoB::getSomeParticularInfo

入口在C::C()已經運行兩個構造爲AB已經在運行點該訂單。因此任何呼叫getSomeParticularInfo將解析爲B::getSomeParticularInfo

注意:一般來說,我會避免在構造函數中使用虛擬方法。一般來說,這是一種不好的做法,因爲它可能造成混亂。

0

是的。如果你從C調用getSomeParticularInfo()它將是來自B的m_steer

上面代碼片段的唯一問題是你不應該從構造函數調用虛擬方法。

1

它將調用B::getSomeParticularInfo()

這功能,編譯會故意忽略A::m_steer並不會意識到C::m_steer存在。

1

這將是的B m_steer除非你明確地從A喜歡叫它:

A::getSomeParticularInfo()