下面的类包含一些相同类型的成员:
template <typename T>
class MyClass
{
T m0;
T m1;
T m2;
T m3;
T m4;
//...
};
成员都是在没有中间访问说明符的情况下声明的,因此分配给后面的成员具有更高的地址(ISO/IEC 14882:9.2.12)。同段说:
Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).
现在让我们假设 MyClass 没有虚函数,也没有虚基类。以下总是正确的吗?
//inside a member function of MyClass
(char*)&m0 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 0
(char*)&m1 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 1
(char*)&m2 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 2
(char*)&m3 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 3
(char*)&m4 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 4
或者是否允许编译器使用比所需的任意更多的填充(无论出于何种原因......)?例如:如果 sizeof(T)==4 和 alignof(T)==8,编译器将在成员之间使用 4 个填充字节。仅在 m2 和 m3 之间使用 12 个填充字节是否有效?
MyClass有虚函数或虚基类时怎么办?编译器真的允许在任意数据成员之间插入与 MyClass 相关的信息(如 vtable-ptr)吗?还是上面标准中的句子与 T 的虚函数和虚基类更相关?因为如果在 T 之外存储与 T 相关的信息是有效的,那么它也可能具有以下含义:
template <typename T>
class MyClass
{
T m0;
//space to manage virtual functions and base classes of m0
//padding
T m1;
//space to manage virtual functions and base classes of m1
//padding
T m2;
//space to manage virtual functions and base classes of m2
//...
};
什么又可以给出一个规则的模式。
最佳答案
没有。没有规则强制要求它,因此编译器可以在任何地方插入填充。 “对齐要求可能……”只是一个例子,并不限制可能的原因。
如果你有一个 T m[5]
成员,情况就不同了,在这种情况下 &(this->m[1]) - &(this->m [0]) == 1
。
出于同样的原因,“编译器真的允许在任意数据成员之间插入与 MyClass 相关的信息(如 vtable-ptr)吗?”必须正面回答,因为没有禁止的规则。它无法将其插入子对象的中间(无论是 T
还是 T[5]
),但在子对象之间没问题。
关于c++ - 相同类型的类成员之间的填充总是相同的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3140096/