2012-04-03 9 views
0

基本クラスまたは派生クラス関数のどちらを呼び出すかについて、(実行時の)内部的にどのように決定されますか。決定は、(FNを呼び出すために取られる方法を以下のサンプルコードで)BFN2の()します。派生クラス関数または基本クラス関数を呼び出すかどうかは、実行時にどのように決定されますか?

Class A { 
    virtual void fn() { std::cout << "A" < <std::endl; } 
    virtual void fn2() { std::cout << "A-fn2" < <std::endl; } 
    }; 

Class B : A 
{ 
    void fn() { std::cout << "B" < <std::endl; } 
} 

int main() { 
    B b = new B; 
    A *a = &b; 
    a->fn(); 
    a->fn2(); 
} 

出力BA-FN2()

基本的にどのように決定派生クラス関数または基本クラスの関数を呼び出すかどうか、実行時に行われるでしょうか?コンパイルエラーを修正した後、あなたの質問に対する答えは、出力が可能になるということです

+5

おそらくコンパイルすることはできません: -

このC++よくある質問は良いさらに読むのですか?また、[vtables](http://en.wikipedia.org/wiki/Virtual_method_table) –

+4

-1ではなく、実際のコード –

+0

を参照してください.Virtualキーワードを追加するのを忘れました。それについての謝罪。 **決定がどのように取られたかを詳しく説明できますか?**インタビュアーは内的なインパネーションを知ることが特にありました。彼は**仮想テーブルと呼ばれるものを暗示した** –

答えて

1

動的/実行時多型とします。
ルールは次のとおりです。
実行時に呼び出すメソッドは、ポインターが指す実際のオブジェクトに応じて、実行時に選択されます。
コンパイラがどのようにこれを行うかは、完全に実装に依存します。通常、コードは、内部の動作ではなく、動作に依存する必要があります。しかし、すべての既知のコンパイラは、仮想ポインタ(vtbl)&仮想ポインタ(vptr)メカニズムを介してこのメ​​カを実装します。

実行時の多型はどのように実装されていますか?

クラスがクラスが多型クラスとして知られvirtual方法があり、コンパイラはそのクラスのvtblを作成したら。 vtblは、そのクラス内のすべての仮想メソッドのアドレスを格納します。コンパイラはまた、そのクラスのすべてのオブジェクトに特別なポインタvptrを追加します。 vptrポイント(のアドレスを格納)はvtblになります。
クラスがそのような多相クラスから派生すると、コンパイラは派生クラスのvtblのメソッドのアドレスを、派生クラスのオーバーライド関数のアドレスに置き換えます。オーバーライドされていないメソッドの場合、アドレスは依然としてBaseクラスのものですメソッド。

したがって、各クラスは通常1つのvtblを持ちますが、各オブジェクトインスタンスはvtblを指すvptrを持ちます。各クラスのvtblは、自身の仮想メソッドのアドレスを格納します。

実行時に、thisポインタ内部vptrがフェッチされ、vtblで適切な方法のアドレスをさらにフェッチ&は、それが呼び出された場合、このメカニズムは、動的ディスパッチ呼ばれます。
したがって、このメカニズムにより、ポインタが指すオブジェクトのタイプに応じて、呼び出される適切なメソッドを決定することができます。右、
Inheritance — virtual functions

1


A A-FN2

実行時の意思決定を必要とするコードには、virtualという機能がありません。コンパイラ自体は関数の呼び出しを評価します。

は、あなたがして、実行時になって、関数呼び出しの決定がと呼ばれるオブジェクトに基づいてhappensがAさんmethodss virtualを作るとします。

+0

私はVirtualキーワードを追加するのを忘れてしまった。それについての謝罪。 **決定がどのように取られたかを詳しく説明できますか?**インタビュアーは内的なインパネーションを知ることが特にありました。彼はいくつかのことを暗示しました**仮想テーブル** –

+1

@NiklasB:これは実装に依存していることを指摘するのは良いことですが、**すべての**既知のコンパイラは仮想テーブルとポインタメカを使って動的ディスパッチを実装しています。正しいものは本当に有効ではありません。 –

+0

@Als:それで、私はvtableに関する答えを書いてきました。乾杯。 –

関連する問題