0

仮想関数に関して少し混乱しています。

仮想関数 foo() を持つ基本クラスがあり、その関数が派生クラスでオーバーライドされたとします。

   class Baseclass
   {  
   public:
       virtual void foo()
       {
           //...
       }
   };

   class Derived: public BaseClass
   {
   private:
       int member_val;
   public:
       Derived( int init )
           : member_val( init )
       {}
       void foo()
       {
           member_val++;
       }
   };

このコードを書くと、派生クラスのメンバー値を使用してfoo

Derived d( 10 );
Base* bPtr = &d;
bPtr->foo(); 

_vptr が「派生クラス仮想テーブル」を指し、「派生クラス仮想テーブル」のポインターが派生クラスの foo() を指しているため、派生クラスに対して foo() が呼び出されましたが、どのようにして member_val が見つかったのか、ベース ポインターがわかりません。それについて。Derived クラスから foo() に渡される "this" とは。Base* (これは Base 型) に対して呼び出しますが、 member_val を見つけるには Derived* (この Derived 型) が必要です。では、ボンネットの下でどのように機能するのでしょうか?

4

1 に答える 1

0

正しい質問は半分の答えです。あなたの場合のように、にthis渡されるものを尋ねたところDerived::foo()、答えは「同じ」です。class のオブジェクトを作成しますDerived。次のようにメモリに割り当てられます。

Derived:
--------
vptr_t* vptr
int member_val

次に、 をキャストします。&dこれはDerived*ですBase*。ポインタはどうした?何もない。指している実際のアドレスではなく、型を変更しただけです。またはをDerived*使用して変換することもできます。この場合、両方を使用することは絶対に安全です。dynamic_cast<Derived*>()static_cast<Derived*>

では、唯一の実際の問題は、仮想関数のテーブルがどのように機能するかということです。しかし、これは別の質問であり、あなたはそれを理解しているようです.

注意: 複数の基本クラスが次々とメモリ内にある場合、多重継承では事態がより複雑になります。

于 2013-06-20T21:25:35.703 に答える