2016-06-09 25 views
1

我有3個類:ABAnotherClass。凡BA得出:基類方法被調用而不是派生,即使通過引用傳遞

class A { 
public: 
    A(){} 
    virtual void method() {//default action} 
}; 

然後,我有一個派生類,B:

class B : public A { 
public: 
    B(){} 
    void method() {//redefine action} 
}; 

而且AnotherClass

class AnotherClass { 
public: 
    AnotherClass(A& a); 
    A a; 
    anotherMethod(){ a.method()} 
}; 
AnotherClass :: AnotherClass(A& a) : a(a) //initialization 

所以,如果我構建與AnotherClass對象B的一個對象:

B b(); 
AnotherClass myObj(b); 

請記住,由於B繼承自A,並且AnotherClass接受A的對象,因此我能夠成功傳入B對象作爲參數。

我呼籲:

myObj.anotherMethod(); 

我希望這個執行anotherMethod(),當它發生了,我希望它來調用屬於B重新定義method(),而是它調用A定義的默認method()

我在想我的問題是因爲我指定了AnotherClass作爲class A的一個對象的參數。但是,我不想將此參數更改爲class B的對象,因爲我也有類C,DE,它們也直接從A繼承。所以我想使用基類作爲參數類型,所以我不僅僅限於能夠傳遞一個b對象。但是,我在本網站上閱讀了一些較舊的帖子,大多數提議的解決方案是通過引用傳遞派生對象(b),我正在這樣做。

有人可以解釋爲什麼會發生這種情況嗎?

+0

*我想我的問題是因爲我指定AnotherClass的參數爲A類的一個對象*你是對的,你需要在類中存儲一個引用或者指向'A'的指針 – NathanOliver

+0

我編輯過它,但不是這樣:'B b();' - 你的代碼甚至編譯? – Ajay

回答

3

構造函數的參數很好。它是B類型的對象,通過引用A子對象傳遞。問題在於,您只將A子對象(而不是派生對象)複製到成員變量a中。然後,當您撥打a.method()時,那裏只有一個基礎對象,因此調用基礎函數。

解決方法是使成員變量成爲參數的指針或引用(而不是副本)。(請注意,無論哪種情況,您都需要確保傳入的對象至少與AnotherClass對象一樣長。

0

只有當它是一個指針才能工作A* a 查看多態性。 http://www.cplusplus.com/doc/tutorial/polymorphism/

如果你不會知道更多,請閱讀文章

+0

'A * a(b);'是一個彙編錯誤,'A &a(b);'也可以工作 –

+0

錯誤並且完全不相關的問題(當他在AnotherClass構造函數中存儲對A實例的引用時切片) – kfsone

+0

A * a =新的A(b);這是更好的:)對不起 – kemis

2

您切片在構造函數AnotherClass。請注意,您有一個類型爲A的值作爲成員。所以編譯器正在做正確的事情。您撥打a.method()時沒有B

相關問題