据我所知,virtual函数指针表在对象中的位置依赖于编译器。
将这个指针放在对象的开头还是放在对象的末尾有什么利弊?
发布于 2012-06-07 11:52:15
虚函数表的存在依赖于编译器(但所有编译器都是如此),并且位置也不是必须的……在我知道细节的所有编译器中,vptr都存储在对象的开头。原因是它提供了一个统一的位置。考虑一个类层次结构:
struct base {
T data;
virtual void f();
};
struct derived : base {
T1 data;
virtual void g();
};如果vptr存储在对象的末尾,那么对于完整类型base的对象,它将在sizeof(T)字节之后。现在,当您有一个完全类型为derived的对象时,base子对象的布局必须与完整base对象的布局兼容,因此对象中的vptr仍然必须是sizeof(T)字节,它将位于derived对象的中间(从头开始为sizeof(T),结束之前为sizeof(T1) )。因此它将不再位于对象的末尾。
此外,在给定this指针的情况下,虚拟调用需要通过vtable进行间接访问,这基本上是取消对vptr的引用,添加偏移量并跳转到存储在那里的内存位置。如果vptr存储在对象的末尾,则对于每个虚拟调用,在取消对vptr的引用之前,都会向this添加额外的内容。
发布于 2012-06-07 11:05:47
是的,它完全依赖于实现。
对于简单的继承层次结构,它位于对象的开头,但对于复杂的层次结构,它不会位于对象的开头。
无论如何,您编写的任何源代码都不应该依赖于它所在的位置,事实上,您编写的任何代码都不应该依赖于虚拟表或虚拟表指针的存在。
C++标准没有要求通过虚拟表和指针来实现虚拟调度,但是所有主流编译器都是通过表指针机制来实现的,但是所有主流编译器都是通过表指针机制来实现的。
https://stackoverflow.com/questions/10925115
复制相似问题