我知道如果一个类包含任何虚函数,大多数编译器(如果不是全部)都会向它的对象添加一个 vptr 指针。有的将其添加为第一个元素,有的将其添加为最后一个元素。但是 C++ 标准是否要求使用 vptr 和 vtable?理论上,任何编译器都可以以其他方式实现它吗?如果是这样,关于多态对象的存储布局和整体大小的保证是什么(例如,连续内存块中的所有明确定义的字段(+填充))?
我不知道这在各种 C++ 标准之间是否有所不同,这就是为什么我只添加了通用C++
标签。
我知道如果一个类包含任何虚函数,大多数编译器(如果不是全部)都会向它的对象添加一个 vptr 指针。有的将其添加为第一个元素,有的将其添加为最后一个元素。但是 C++ 标准是否要求使用 vptr 和 vtable?理论上,任何编译器都可以以其他方式实现它吗?如果是这样,关于多态对象的存储布局和整体大小的保证是什么(例如,连续内存块中的所有明确定义的字段(+填充))?
我不知道这在各种 C++ 标准之间是否有所不同,这就是为什么我只添加了通用C++
标签。
C++ 标准中没有规定虚拟继承的特定实现。虚拟继承的语义是根据适当的语法和预期结果指定的。C++ 实现可以自由使用产生这些结果的任何技术实现。
例如,让我们从整个基类的虚拟继承开始:
[class.mi]
包含关键字 virtual 的基类说明符指定虚拟基类。...对于指定为虚拟的每个不同的基类,最派生的对象应包含该类型的单个基类子对象。
该标准将语法定义virtual
为引入基类的虚拟继承,以及预期的结果:最派生的对象包含虚拟继承的基类的单个实例。句号。故事结局。特定实现如何做到这一点超出了标准的范围。
同样,对于单个虚函数:
[类.虚拟]
如果虚成员函数 vf 在类 Base 和 Derived 类中声明,直接或间接从 Base 派生... [更多要求] ... 那么 Derived::vf ... 将覆盖 Base::vf。
省略了一些技术要求。该标准仅指定派生类中的虚函数“覆盖”基类中的(相同)函数。没有在任何地方指定特定的 C++ 实现是如何进行的。