2016-10-02 10 views
0

C++の仮想関数の概念を理解しようとしていますが、オンラインで読むのですが、以下のプログラム出力が1ではなく2である理由を理解できません。誰でも説明できますか?C++の仮想関数の概念

Class A 
{ 
    int a; 
    public: 
     A() 
     { 
      a = 1; 
     } 
     virtual void show() 
     { 
      cout <<a; 
     } 
}; 

Class B: public A 
{ 
    int b; 
    public: 
     B() 
     { 
      b = 2; 
     } 
     virtual void show() 
     { 
      cout <<b; 
     } 
}; 

int main() 
{ 
    A *pA; 
    B oB; 
    pA = &oB; 
    pA->show(); 
    return 0; 
} 
+3

なぜ結果が "1"になるのか説明できますか? –

+0

なぜ実際に出力が「1」になるべきだと思いますか? –

+1

この概念を完全に説明したC++の本を読んでください。 –

答えて

1

を支援します。 あなたの例ではあなたはそれが基底クラス(A)へのポインタであるように、多形のpAを使用していますが、あなたはそれにクラスBのオブジェクトを割り当てますA. の子で、あなたはShow()を仮想として宣言しました。

これがポリモルフィズムの主な目標です。つまり、基本ポインタが実行時まで指し示すオブジェクトの種類がわからないことを意味します。例えば:main:

int main() 
{ 

    int choice; 
    cout << "1: A object 2: B object:\n\n"; 
    cin >> choice; 
    if(1 == choice) 
     pA = new A; // result will be 1 
    else 
     if(2 == choice) 
      pA = new B; // result will be 2 

    if(pA) 
     pA->show(); 
    delete pA; 
    pA = NULL; 

// B* pB = new A; // error: cannot convert from class A* to class B* because C++ is not contravariant 
    B* pB = new B; 
    pB->show(); // result: 2 

    delete pB; 
    pB = NULL; 

    return 0; 
} 
1

cppreferenceからの仮想関数は、その動作が派生クラスでオーバーライドすることができますメンバ関数です。非仮想関数ではなく、オーバーライドされた動作は、クラスの実際の型に関するコンパイル時の情報がなくても保持されます。 派生クラスがポインターまたは基本クラスへの参照を使用して処理される場合、オーバーライドされた仮想関数を呼び出すと、派生クラスで定義された動作が呼び出されます。関数の名前は、スコープ解決演算子の右側に表示された場合、この関数は、それがある(修飾名のルックアップを使用して選択されている場合、この動作は抑制されている:あなたは、クラス Bshow()をオーバーライドしている、ので:)

pA->show()は、show()をクラスBに呼び出します。
希望、これはあなたがオーバーライド仮想関数とポインタとポリモーフィズムを実現