2010-07-19 220 views
1

我有一個類,像這樣:C++繼承問題

class A 
{ 
    public: 
     virtual void foo() { bar() } 

    protected: 
     virtual void bar() { /* do stuff */ } 
} 

現在我想一個派生類B中會覆蓋foo和酒吧。所以我寫了以下內容:

class B : public A 
{ 
    public: 
     virtual void foo() { A::foo(); /* then other stuff */ } 

    protected: 
     virtual void bar() { /* do different stuff */ } 
} 

一切編譯,但是當我調用B :: foo的我希望B ::酒吧得到(最終)調用。相反,我得到A :: bar。我究竟做錯了什麼?

+3

您忘了將所有指針增加42. – 2010-07-19 16:51:41

+1

您是如何聲明您的「B」實例的? – reuscam 2010-07-19 16:52:09

+1

您能告訴我們您是如何調用它們的嗎? – Tom 2010-07-19 16:52:24

回答

2

由操作員更新之前。

這應該工作

A* b = new B(); 

b->bar(); //Notice that this is just an example 

還與引用

工作
void B::foo(){this->bar();} 

    B b; 
    A& ab = b; 
    ab.foo(); //calls B::bar() 
+1

您的更新沒有任何意義。如果他*明確地調用了'A :: bar',這將是正確的(儘管'this->'仍然是多餘的),但是再看看他的代碼:他明確地調用了'A :: foo',依次調用'bar()'。由於'bar'是虛擬的,因此它應該像他所期望的那樣解析爲'B :: bar'。 – 2010-07-19 17:11:46

+0

好吧然後即時將它取出 – Tom 2010-07-19 17:18:03

+1

b-> bar()將不會工作,因爲該成員受保護。您對B :: foo()的重新定義不是OP想要的。他希望它首先調用A :: foo()的基本實現。 – 2010-07-19 17:39:53

9

一切編譯,但是當我調用B :: foo的我希望B ::酒吧得到(最終)調用。相反,我得到A :: bar。我究竟做錯了什麼?

看起來你並沒有真正理解了什麼錯在你的原代碼,決定虛擬控機制必須是罪魁禍首,然後你張貼了非工作示例描述你是什麼傾向於相信,但你沒有打擾檢查,因爲如果你有,那麼你看到它不公開所描述的行爲。這是你的例子的可編譯版本。

#include <stdio.h> 
class A 
{ 
    public: 
     virtual void foo() { puts("A:foo()"); bar(); } 

    protected: 
     virtual void bar() { puts("A:bar()"); } 
}; 

class B : public A 
{ 
    public: 
     virtual void foo() { puts("B:foo()"); A::foo(); } 

    protected: 
     virtual void bar() { puts("B:bar()"); } 
}; 


int main() 
{ 
    B b; 
    b.foo(); 
} 

當我運行此我得到:

$ g++ g++ h.cc 
$ ./a.out 
B:foo() 
A:foo() 
B:bar() 

所以,一切都很好用B ::巴()。

+1

確實。問題在於創建對象的代碼並調用函數(我們未顯示)或解釋結果。 – 2010-07-19 17:40:28

0

除了類定義末尾缺失的分號以外,當前的OP代碼按預期工作。