2016-06-29 32 views
0

我似乎無法理解編譯器的優先級如何去哪個函數。 這裏是一個例子代碼:C++繼承選擇函數的優先級

#include <iostream> 
using namespace std; 

class A{ 
public: 
    int f() {return 1;} 
    virtual int g() {return 2;} 
}; 
class B: public A { 
public: 
    int f() {return 3;} 
    virtual int g() {return 4;} 
}; 
class C: public A{ 
public: 
    virtual int g() {return 5;} 
}; 
int main() { 
    A *pa; 
    B b; 
    C c; 

    pa = &b; 
    cout<< pa -> f()<<endl<<pa -> g() << endl; 
    pa = &c; 
    cout<< pa -> f() << endl; cout<< pa -> g() << endl; 

    return 0; 
} 

哪個函數(G()和f())將每個時間稱爲爲什麼?

+2

運行該程序找出並返回這裏,如果你不能找出*爲什麼*代碼的行爲就像它一樣。但首先,嘗試使用關於虛擬調度的知識來解釋自己。 – user2079303

+0

我跑了它,問題是爲什麼... – user107761

+1

如果你跑了它,那麼你一定知道哪個函數被調用,你不是嗎?你確實問過。 – user2079303

回答

0

在第一個序列中,它將調用A::f()B::g()

在第二個序列中,它將調用A::f()C::g()

原因是f()作爲非虛擬方法在編譯期間根據變量類型(指向A)解析。 g()A中被標記爲虛擬方法,因此運行時解析完成並且將始終調用實際實例的方法(BC)。

1

pa->f()總是會調用A::f(),不管你做pa點,因爲paA*A::f虛擬

  • 如果pa指向B(第一順序),它會調用B::g()

    pa->g()A::g()B::g()C::g()取決於什麼pa點使用polymorphism因爲A::g虛擬調用。

  • 如果pa指向C(第二個序列),它將調用C::g()
0

當你說一個函數是virtual時,你告訴編譯器使用後期綁定而不是靜態綁定。 因此在編譯期間A::f()將是靜態綁定,所以它是固定調用哪種方法體。 另一方面,A::g()在編譯期間不會綁定到任何方法體。它將在運行時決定調用哪個方法體(使用vptr)。

A *pa; //no matter what object you assign to pa, A::fa() will always be called 
pa = &b; 
pa->f();//calls A::f() 

pa->g();// remember what function body to be called will be decided at runtime. 
//will call B::f() 

pa = &c; 
pa->g(); //will call C::g()