哪个虚拟表将是纯虚函数所在?在基类还是派生类?
例如,每个类中的虚拟表是什么样的?
class Base {
virtual void f() =0;
virtual void g();
}
class Derived: public Base{
virtual void f();
virtual void g();
}
g++ -fdump-class-hierarchy layout.cpp
产生一个文件layout.cpp.class
。的内容layout.cpp.class
将显示如下:
用于基础的 Vtable Base::_ZTV4Base: 4u 条目 0 (int (*)(...))0 8 (int (*)(...))(& _ZTI4Base) 16 __cxa_pure_virtual 24 基地::g 类库 大小=8 对齐=8 基本尺寸=8 基本对齐=8 Base (0x7ff893479af0) 0 几乎为空 vptr=((& Base::_ZTV4Base) + 16u) 导出的 Vtable Derived::_ZTV7Derived: 4u 条目 0 (int (*)(...))0 8 (int (*)(...))(& _ZTI7Derived) 16 导出::f 24 派生::g 类派生 大小=8 对齐=8 基本尺寸=8 基本对齐=8 派生 (0x7ff893479d90) 0 几乎为空 vptr=((& Derived::_ZTV7Derived) + 16u) 基数 (0x7ff893479e00) 0 几乎为空 主要派生(0x7ff893479d90)
删除 'pureness'f
将第五行更改为:
16 基地::f
每个类都有自己的 vtable。f
in的入口Base
将是NULL
,而 in 的入口Derived
将是指向已实现方法的代码的指针。
vtable 条目将位于基类中。
为什么?因为您可以拥有一个包含派生类型对象地址的基指针类型,并且仍然调用基类型的指针变量上的方法。
纯虚拟只是告诉编译器派生类型必须提供自己的实现,并且它们不能依赖基类的实现(如果甚至在基类中指定了)
实际上在两者中。基类 vtable 将有一个纯虚函数的插槽,指向pure_virtual_function_called()
可能会中止程序的存根之类的东西,而派生类 vtable 将有一个指向实际实现的指针。