在我之前的一篇文章 “COM 对象的内存布局”中,作为举例,我将对象的虚函数表指针放置在了底层 C++ 对象的起始位置,但是值得注意的是,虚函数表指针指向的位置并没有一个实际的标准。即使将虚函数表放置在对象中间,甚至是放在对象的结尾,都是完全合法的,只要虚函数表中的函数指针能正确的定位它需要调用的底层 C++ 对象的实际位置就可以了。
确实,在那篇文章中的第二张图里,你可以看到,我们将指针 “q” 指向了对象的中间的位置,而不是它的起始位置。
下面我举个实际的例子,演示了虚函数表放置在对象的结尾位置的情况。
>> 请移步至 topomel.com 以查看图片 <<
下图是对象可能的内存布局:
>> 请移步至 topomel.com 以查看图片 <<
在上面的特殊的代码示例中,我们可以看到,对象的虚函数表放置在了对象的结尾,而不是起始位置。这完全是一个合法的情况。
尽管通常我们会认为虚函数表应该放在对象的起始位置,COM 不要求以这种方式实现。
如果你想把你的虚函数表放在最后,并使用负的偏移量来访问对象的成员,那么也是可以的,只是相关麻烦一些。
总结
虚函数是 C++ 实现动态绑定的基础,这话,我妹说错吧?
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《The vtable does not always go at the start of the object》