在回答其中一个问题时,有一个讨论主题below my answer。这表明取决于访问说明符(或可能是继承的类型)private/protected/public
,sizeof
class
对象可能会有所不同!
我仍然不清楚他们的简短讨论,这怎么可能?
答案 0 :(得分:15)
请注意下面的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
重新排序到b
之前,强制在{{{}之间插入额外的填充填充。 1}}和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
};
。
在C ++ 11 中,语言略有变化。 N3485 9.2 [class.mem] / 13说(强调我的):
分配具有相同访问控制的(非联合)类的非静态数据成员(第11条),以便后面的成员在类对象中具有更高的地址。 未指定具有不同访问控制的非静态数据成员的分配顺序(第11条)。实施对齐要求可能导致两个相邻成员不能立即分配;所以可能需要空间来管理虚函数(10.3)和虚基类(10.1)。
这意味着在C ++ 11中,在上面的示例中(由3个公共分隔),仍然不允许编译器执行重新排序。它必须是
之类的东西sizeof(Foo) == 8
,它使class Foo
{
char a;
public:
int b;
protected:
char c;
};
,a
和b
具有不同的访问控制权。
请注意,在C ++ 11规则下,给出了如下定义:
c
编译器必须在class Foo
{
char a;
public:
int b;
protected:
char c;
public:
int d;
};
之后放置d
,即使它们被访问说明符分开。
(那就是说,我不知道任何实际利用任何标准提供的纬度的实现)