2015-07-21 187 views
2

此示例顯示派生類對象被傳遞給引用基類作爲參數的函數。派生類中的成員函數g(int)g(float)隱藏在基類中。我明白,我的問題與此無關。將派生對象作爲基類參考參數傳遞

class Base { 
public: 
    virtual void g(float x) throw() 
    { 
     cout << "Base::g(float)\n"; 
    } 
}; 

class Derived : public Base { 
public:   
    virtual void g(int x) throw() // Bad: Hides Base::g(float) 
    { 
     cout << "Derived::g(int)\n"; 
    } 
}; 


void sampleTwo(Base& b, Derived& d) 
{ 
    b.g(3.14f); 
    d.g(3.14f); // Bad: Converts 3.14 to 3 and calls Derived::g(int) 
} 

int main() 
{ 
    Derived d; 
    sampleTwo(d, d); 
    return 0; 
} 

輸出是:

Base::g(float) 
Derived::g(int) 

我的問題是與輸出 「基礎::克(浮動)」。由於sampleTwo()中由'b'引用的對象是派生對象,因此動態綁定不應該調用派生類的g()方法(將float轉換爲int)?

+0

在編寫派生類的函數以覆蓋基類的虛擬時,開始使用「override」關鍵字(假定編譯器具有合理的C++ 11支持)是一個好主意。這樣,如果函數實際上沒有按照你的意圖重寫,編譯器可能會給你一個錯誤。 – TheUndeadFish

+0

我也很驚訝,但我最初的猜測是看到base :: g(float)調用兩次,而不是派生:: g(int),因爲函數調用在兩種情況下都匹配g(float)的簽名,這是一個不同的函數g(int)(這是兩個不同的函數,你的代碼不會覆蓋) –

+0

你應該在'Derived'中使用Base :: g'來取消隱藏'Base :: g(float) '。 – WorldSEnder

回答

1

動態分派調用最終的覆蓋。由於Derived::g隱藏而不是覆蓋Base::g,因此的最終覆蓋Derived仍爲Base::g

0

g(float)g(int)是不同的功能成員。如果你想Derived工作,你必須在這兩個類中使用g(float)

g()可以被重載檢查出函數重載: https://en.wikipedia.org/wiki/Function_overloading

實施例(g(float)g(int)在同一類和獨立的功能):

class Derived : public Base { 
public: 

    void g(float x) throw(); 
    void g(int x) throw(); 

}; 
3

g(int)g(float)是兩種完全不同的方法。 Derived::g(int)不會覆蓋Base::g(float)。這些方法是無關的。

由於Derived不覆蓋g(float),您對b.g(3.14f)的期望是沒有根據的。如預期的那樣,b.g(3.14f)應該叫Base::g(float)

如果您在Derived中覆蓋g(float),那麼b.g(3.14f)確實會調用Derived::g(float)

+0

謝謝。現在明白了吧。 – irappa