2016-06-29 2 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()が呼び出されます。

2番目のシーケンスでは、A::f()C::g()が呼び出されます。

これは、非仮想メソッドとしてf()が変数タイプ(Aへのポインタ)に従ってコンパイル時に解決されるためです。 g()Aに仮想メソッドとしてマークされているため、実行時の解決が行われ、常に実際のインスタンス(BまたはC)のメソッドが呼び出されます。

1

pa->f()はいつもあなたがpaA*で、A::f仮想ではないためにpaポイントを作るものは何でも、A::f()を呼び出します。

  • B(最初のシーケンス)にpaポイント、それはB::g()を呼び出します場合:A::g仮想あるので

    pa->g()polymorphismを使用することに何のpaポイントに応じてA::g()B::g()またはC::g()を呼び出します。

  • paC(第2のシーケンス)を指している場合は、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() 
関連する問題