假设:
Class A{
float one;
float two;
float three;
//... many, many member functions, and maybe static functions too ..
}
我是否可以假设,无论此类中有多少函数,以下通常应该为真:
sizeof(A)==sizeof(float)*3
这样我什至可以断言:
static_assert(sizeof(A) == sizeof(float) * 3, "你的类正在填充内存。");
这准确吗?
现在,假设类 A 继承自另一个类。我假设以上内容不是是真的,而是您必须在 sizeof
断言中包括从基类添加 ivars 的大小?
如果“A 类”具有虚函数或派生自具有虚方法的类,则
sizeof(A) 无法通过手动汇总数据成员来准确确定。
这是因为编译器插入了一个名为 v-pointer 的隐藏指针,它指向 v-table。
如果你有虚拟基类,事情会变得更复杂,因为编译器可能会插入一个隐藏的 v-base-pointer。
此外,这些隐藏指针在多态 C++ 对象的内存模型中的插入位置在编译器实现中会发生变化(因为这些细节不是 C++ 标准的一部分)。
这就是为什么我们无法实现使用 C++ 开发的应用程序的二进制接口(interface)兼容性(编译一次并在所有平台上重用)的原因之一。
(同样,这是发明 .Net 和 Java 的另一个原因!)。
简而言之,“C++”中的多态类的内存模型与“C”的内存模型不匹配(这就是我们在 C++ 中使用 extern“C”的原因之一)。