vptr是否位于对象的开头?

时间:2012-09-19 13:15:04

标签: c++ visual-c++ rtti virtual-functions dynamic-cast

根据MSDN,__RTDynamicCast() function用于在Visual C ++中实现dynamic_cast。其中一个参数是LONG VfDelta,它被描述为“对象中虚函数指针的偏移量”。

AFAIK vptr始终位于对象的开头,因此偏移量始终为零。我仔细研究了使用dynamic_cast对各种代码片段的反汇编,我从未见过任何东西,只有零代替这个参数。

vptr是否位于对象的任何位置?这种偏移可以是零吗?

3 个答案:

答案 0 :(得分:5)

如果是多重继承,则有多个vptr,您需要offset。看看这里:http://hacksoflife.blogspot.com/2007/02/c-objects-part-3-multiple-inheritance.html

答案 1 :(得分:2)

我不知道微软做了什么,但vtable指针位于偏移零点并不总是正确的。它可能不是多重继承的情况的一个例子(特别是如果涉及虚拟基类)。

编辑:

我将通过示例扩展一下。

如果第一个基类或类没有vtbl,派生类将不会在偏移量0处具有vtbl指针(这种继承是不好的做法,但语言允许)。

如果存在虚拟基础,派生类通常会在偏移0处具有指向虚拟基础的指针,而不是指向vtbl的指针。

答案 2 :(得分:1)

虚拟继承退出时使用此功能(想想钻石继承图表)。此偏移量是类本身在对象内的偏移量。

如果B和C来自A,则D来自两者。

   A
 /   \
B     C
 \   /
   D

然后B和C可以在D中按任意顺序排列。这是偏移量发挥作用的地方。因此,当您将类型A的对象dynamic_cast类型化为B时,它可能会有所不同,具体取决于实例是B类型还是D类型。

最后为了说明,这里可能是不同类的布局

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

在这种情况下,B的虚函数表的偏移可以是0(B实例),或sizeof(A)+ sizeof(C)(D实例)