vptr是一种隐藏的数据成员,用来支持虚函数技术的,它被编译器插入到类里。虚指针指向一个表格,这个表格包含了类中所有虚函数的地址。每个类通常有一个这样的表格,每一个对象实例都含有一个指向那表格的指针。
C++ 标准没有明确规定任何有关虚函数实现方面的细节;它只是准许写编译器的人要在多态类中添加一个vptr。至少在理论上,写编译器的人可以以任何方式实现虚函数,而不是必须使用 vptr。实际上,所有的C++编译器用同一种办法来实现虚函数,即:在类中增加一个我们所谈到的隐藏指针。
C++ 标准也没有明确规定 vptr 的地址。实际上,也只有两种解决方式:把 vptr 放到类的开头(在所有用户声明数据成员的前面),或者放到类的末尾(在所有用户声明数据成员的后面)。
在原先那篇文章中,我选择了序列化作为“查明 vptr 位置”的例子。读者指出,在那个例子中,根本用不着查明 vptr 的位置:首先,从文件中读取序列化的对象到空对象中,然后让它的缺省构造函数运行。用这种方式,构造函数就会覆盖掉坏的 vptr ,用正确的值替换 vptr。
下面是知道 vptr 位置的应用实例。例如:你可以调试由你的编译器产生的汇编代码。知道了 vptr 位置所在后,你就能够计算出虚成员函数的地址。
最后,要记住,你不需要为每一个类都去查明 vptr 的所在。只使用一两个例子就足够了。你的编译器使用同一种方式,对任何一种类都是一视同仁的,要么把 vptr 放在开头,要么放在结尾。