2011-12-03 71 views
6

我在使用引用變量時發現了一個奇怪的行爲。引用變量和虛函數

下面是類實現:

class Base { 
    public: 
     virtual void Method() = 0; 
}; 

class DerivedA : public Base { 
    public: 
     virtual void Method() {} 
} 

class DerivedB : public Base { 
    public: 
     virtual void Method() {} 
} 

這裏是具有奇怪的行爲的示例代碼:

void main(int argc, char *argv[]) { 
    DerivedA a; 
    DerivedB b; 
    Base &base = a; 

    base.Method(); // Calls DerivedA::Method 

    base = b; 
    base.Method(); // Calls DerivedA::Method!!! Why doesn't call DerivedB.Method()? 
} 

總之,似乎「關聯」的虛函數指針表參考變量僅在初始化參考變量時確定。如果我重新分配參考變量,則vfpt不會更改。

這裏會發生什麼?

回答

13

Base &base是一個參考,即別名到a對象,因此分配base = b相當於a = b,其離開base的thingie仍然是相同的類的同一個對象。你似乎假設這不是指針的重新分配。

+5

我認爲這個答案值得綠剔! – Walter

+2

是的,我認爲這應該是被接受的答案。 – Rafid

+0

謝謝,雖然接受的答案是一個提問者已經接受,並且沒關係,他接受了其他答案;-) –

7

引用只能初始化一次。您不能將新對象分配給引用。這裏實際發生的是Base的operator =被調用,而底層對象仍然是DerivedA而不是DerivedB。

+2

每天總有一些東西需要學習。 – Luca

+0

我不確定這實際上是否正確。 operator =沒有在Base中定義,所以除了operator =的C++默認實現之外,沒有什麼可以調用的。我想這裏發生的是@MichaelKrelin下面的回答。 – Rafid

+0

@Rafid在你寫的時候,有一個operator =的默認實現。默認實現不是虛擬的,並且基類的類型是Base,所以調用Base :: operator =()。邁克爾的回答也是正確的。這兩個答案並不矛盾。 – selalerer