3

MSDN によると、Visual C++ での実装には__RTDynamicCast() 関数が使用されます。dynamic_castそのパラメーターの 1 つは、LONG VfDelta「オブジェクト内の仮想関数ポインターのオフセット」として記述されています。

AFAIKvptrは常にオブジェクトの先頭にあるため、オフセットは常にゼロになります。を使用してさまざまなコード スニペットの逆アセンブルを詳しく調べましたdynamic_castが、このパラメーターの代わりに 0 以外が渡されているのを見たことがありません。

vptrオブジェクトの開始以外の場所に配置されたことはありますか? このオフセットはゼロ以外にできますか?

4

3 に答える 3

5

多重継承の場合、複数の継承がvptrあり、offset. こちらをご覧ください: http://hacksoflife.blogspot.com/2007/02/c-objects-part-3-multiple-inheritance.html

于 2012-09-19T13:17:56.097 に答える
2

Microsoft が何をしているのかはわかりませんが、vtable ポインターがオフセット 0 にあるとは限りません。そうでない場合の例は、多重継承の場合です (特に、仮想基本クラスが関係している場合)。

編集:

例を使ってこれを少し拡張します。

最初のベースまたはクラスに vtbl がない場合、派生クラスはオフセット 0 に vtbl ポインターを持ちません (このような継承は悪い習慣ですが、言語では許可されています)。

仮想ベースがある場合、派生クラスは通常、vtbl ポインターではなく、オフセット 0 にある仮想ベースへのポインターを持ちます。

于 2012-09-19T13:19:33.380 に答える
1

この機能は、仮想継承が終了するときに使用されます (ひし形の継承チャートについて考えてください)。このオフセットは、オブジェクト内のクラス自体のオフセットです。

B と C が A から派生し、D が両方から派生した場合。

   A
 /   \
B     C
 \   /
   D

次に、B と C は D でどちらの順序でもかまいません。ここでオフセットが機能します。したがって、タイプ A のオブジェクトをタイプ B に dynamic_cast すると、インスタンスがタイプ B か D かによって異なる場合があります。

最後に説明するために、異なるクラスの可能なレイアウトを次に示します

Class B:  Class C:   class D:
 | A |      | A |     | A |
 | B |      | C |     | C |
                      | B |
                      | D |

この場合、B の仮想関数テーブルのオフセットは、0 ( B インスタンスの場合) または sizeof( A ) + sizeof( C ) ( D インスタンスの場合) のいずれかになります。

于 2012-09-19T13:28:09.733 に答える