2017-07-20 140 views
0

我想撥打B::func2(int x, int y)A::func1(x),如何申報?C++繼承,如何在基類的方法中調用子類的方法?

class A { 
public: 
    void func1(int x); 
    virtual void func2(int x, int y); // do not need implement in A 
}; 

class B : public A { 
public: 
    void func2(int x, int y) override; // override 
}; 

void A::func1(int x) { 
    int y; 
    func2(x, y); // I want to use the version of A's subclass 
} 

int main() 
{ 
    B b; 
    b.func1(x); // call A::func1(x) first then call B::func2(x, y) 
} 

它不會編譯,而是下面的錯誤信息顯示

> clang++ test.cpp -std=c++11

Undefined symbols for architecture x86_64:

"typeinfo for A", referenced from:

typeinfo for B in test-bbac7f.o 

"vtable for A", referenced from:

A::() in test-bbac7f.o 

NOTE: a missing vtable usually means the first non-inline virtual member > function has no definition.

ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

+4

您顯示的代碼不會出現這種情況嗎?你如何測試它?你得到了什麼結果,你期望得到什麼結果? –

+2

爲什麼你要在'A :: func1()'中調用'B :: func2()'?如果實際對象不是'B',你需要什麼? – Peter

回答

1

幾件事情:

1.)通過追加=0;來僞造A::func2,或者使用大括號{}來定義它的主體(注意它可以留空)。

2.)使用大括號{}(同樣可以留空)定義B::func2的正文。

你不能調用一個未定義的函數。

2

// call A::func1(x) first then call B::func2(x, y)

這正是你的情況會發生什麼。見at Coliru

基本上,這就是虛擬通話的內容。由於func2被標記爲「虛擬」,因此當它被調用A::func1時,該調用將通過vtable進行,因此將調用覆蓋方法B::func2

這是反之亦然:如果你想A::func1調用A::func2,你就必須把它明確寫入:

void A::func1(int x) { 
    int y; 
    A::func2(x, y); // explicitly tell to use A's version; otherwise the overriden method from the subclass is invoked. 
} 

附:This answer建議使A::func2純虛擬。這可能是有道理的,如果你不打算使用A::func2的實現。如果出於某種原因,你需要有內A::func2一些功能代碼爲好,那麼典型的模式是將呼叫在派生類中添加A::func2,這樣

void B::func2(int x, int y) { 
    A::func2(x, y); 
    // do something specific for B 
} 
相關問題