2016-04-24 28 views
0

私は仮想関数および仮想テーブルの基本的な概念を理解し、 なぜc.A();プリントアウト仮想関数クラスのメンバ関数内で呼び出し

parent A 
child 

が、仮想キーワードなし次の例では、私は理解していませんParent :: func()の場合は、

parent A 
parent 

詳細をお知らせください。 vテーブル、メモリ(ヒープ、スタック)などで説明することは素晴らしいことです。

ありがとうございました。

#include <iostream> 

template <class TYPE> class Parent 
{ 
public: 
    Parent() {}; 
    ~Parent() {}; 
    virtual void func() { std::cout << "parent" << std::endl; }; 

    void A() { 
     std::cout << "parent A" << std::endl; 
     func(); 
    } 

}; 

template <class TYPE> class Child : public Parent <TYPE> 
{ 
public: 
    Child() {}; 
    ~Child() {}; 

    void func() { std::cout << "child" << std::endl; }; 
}; 

void main() 
{ 
    Child<int> c; 
    c.A(); 
} 

答えて

2

仮想キーワードは、派生クラスで関数を再定義できるように指定しますが、参照を通じて呼び出しプロパティを保持します。これは基本的に多態的な振る舞いの引き金です。関数が仮想宣言され、派生クラスで再定義された場合、vtableは、特定の名前空間が指定されていない限り、関数の適切なバージョンを選択するために利用されます。たとえば、Parent :: func()などです。同じ名前を持っているにも関わらず、キーワードvirtualではなく、func()という名前の2つの関数は全く異なっています。派生クラスの関数のバージョンにアクセスできる基本クラスには参照がありません。これは、基本クラスで定義されているバージョンfunc()のみを使用します。

0

@Pemdasは素敵な説明を与えました。ここで私の試しです。

c.A()は、コンパイラに対して、「私の親クラスで定義された非仮想関数Aを呼び出すつもりです。これは、クラスParentA方法「が第1行目の関数ポインタを取得し、それを呼び出して、オブジェクト& Cのvtableの取得」に変換Parent::A(&c)

に変換されます。 cは関数funcを再実装するので、関数ポインタはcの関数funcの実装になります。それはあなたが見るものでしょう。

関連する問題