在回答其中一个问题时,我的回答下方有一个讨论线程。这表明根据访问说明符(或可能是继承类型),private/protected/public
对象可能会有所不同!sizeof
class
从他们的简短讨论中我仍然不明白,这怎么可能?
在回答其中一个问题时,我的回答下方有一个讨论线程。这表明根据访问说明符(或可能是继承类型),private/protected/public
对象可能会有所不同!sizeof
class
从他们的简短讨论中我仍然不明白,这怎么可能?
请注意以下 C++11 的新语言
在 C++03中,有一种语言使这成为可能,9.2 [class.mem]/12(强调我的):
分配没有中间访问说明符的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。由访问说明符分隔的非静态数据成员的分配顺序未指定(11.1)。实现对齐要求可能会导致两个相邻的成员不会被立即分配;管理虚拟功能 (10.3) 和虚拟基类 (10.1) 的空间要求也是如此。
所以给出这个定义:
class Foo
{
char a; //8 bits
// a must come before b, so 3 bytes of padding have to go here to satisfy alignment
int b; //32 bits
char c; //8 bits
// 24 bits of padding required to make Foo a multiple of sizeof(int)
};
在具有 32 位 ( int
) 对齐的系统上,编译器不允许重新排序c
到 before ,从而强制在 和 之间和之后b
插入额外的填充填充到对象的末尾(制作)。但是,为此:a
b
c
sizeof(Foo) == 12
class Foo
{
char a;
public:
int b;
public:
char c;
};
a
和 (b
和c
) 由访问说明符分隔,因此编译器可以自由地执行这种重新排序,使得
memory-layout Foo
{
char a; // 8 bits
char c; // 8 bits
// 16 bits of padding
int b; // 32 bits
};
sizeof(Foo) == 8
.
在 C++11中,语言略有变化。N3485 9.2 [class.mem]/13 说(强调我的):
分配具有相同访问控制(第 11 条)的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。未指定具有不同访问控制的非静态数据成员的分配顺序(第 11 条)。实现对齐要求可能会导致两个相邻的成员不会被立即分配;管理虚拟功能 (10.3) 和虚拟基类 (10.1) 的空间要求也是如此。
这意味着在 C++11 中,在上面的示例中(由 3 个 public 分隔),仍然不允许编译器执行重新排序。它必须是这样的
class Foo
{
char a;
public:
int b;
protected:
char c;
};
, 哪些地方a
,b
和c
具有不同的访问控制。
请注意,根据 C++11 规则,给出如下定义:
class Foo
{
char a;
public:
int b;
protected:
char c;
public:
int d;
};
编译器必须放在d
之后b
,即使它们由访问说明符分隔。
(也就是说,我不知道任何实际利用任一标准提供的纬度的实现)