根据MSDN,__RTDynamicCast() function用于在Visual C ++中实现dynamic_cast
。其中一个参数是LONG VfDelta
,它被描述为“对象中虚函数指针的偏移量”。
AFAIK vptr
始终位于对象的开头,因此偏移量始终为零。我仔细研究了使用dynamic_cast
对各种代码片段的反汇编,我从未见过任何东西,只有零代替这个参数。
vptr
是否位于对象的任何位置?这种偏移可以是零吗?
答案 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实例)