5

私の質問は、基本クラスの仮想関数を呼び出すオブジェクトスライスの場合に仮想関数がどのように機能するかを説明するこの質問と、以下のコードの派生クラスの仮想テーブルレイアウトを説明するウィキペディアの記事を参照したものです。

    class A{

    public:
     virtual void func(){ cout<<"\n In A:func";}
    };

    class B:public A{

    public:
     virtual void func(){ cout<<"\n In B:func";}
    };

   main(){
    A *ptr1 = new B();

    A oA = *ptr1;

    oA.func(); 
  }




      DerviedClassObjectB:
         +0: pointer to virtual method table of B 

       virtual method table of B:
         +0: B::func

上記のプログラムは "In A::func" を出力します。

しかし、クラス B の仮想テーブルが基本クラス A::func を認識していない場合、どうすれば A::func を呼び出すことになりますか?

4

2 に答える 2

15
A oA = *ptr1;

これにより、メンバー変数が新しいAオブジェクトにコピーされます。vtableポインターは通常のメンバー変数ではなく、コピーされません。したがって、このオブジェクトに対して呼び出される後続の仮想関数は、Aオブジェクトであるため、Aオブジェクトであるかのように動作します

于 2010-08-13T19:27:51.510 に答える
14

「クラスの仮想テーブルB」?クラスの仮想テーブルは呼び出しにまったくB関与しません。oA.func()オブジェクトoAのタイプAは です。これは、その仮想テーブルがクラスの仮想テーブルであることを意味しますA

さらに、ほとんどのコンパイラは呼び出しを最適化してoA.func()、仮想テーブルをまったく使用しないようにします。の型はoAコンパイル時に認識されるため、仮想テーブルを使用せずoA.func()にすぐに呼び出しを行うことができます。A::func

于 2010-08-13T18:37:00.090 に答える