vptr 是否位于对象的开头

Is vptr ever located not at start of object?

本文关键字:对象 开头 是否 于对象 vptr      更新时间:2023-10-16

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

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

除了对象开始之外,vptr是否位于任何地方?这个偏移量可以不是零吗?

在多重继承的情况下,有多个vptr,您需要offset。看看这里: http://hacksoflife.blogspot.com/2007/02/c-objects-part-3-multiple-inheritance.html

我不知道

Microsoft做什么,但 vtable 指针位于偏移量零并不总是正确的。可能不是这种情况的一个示例是多重继承(特别是如果涉及虚拟基类)。

编辑:

我将通过示例对此进行一些扩展。

如果第一个基或类没有 vtbl,

则派生类在偏移量 0 处将没有 vtbl 指针(这种继承是不好的做法,但语言允许)。

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

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

如果 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 实例情况)