对象的大小是否受访问说明符类型和继承类型的影响?

时间:2011-07-05 04:14:14

标签: c++ inheritance access-specifier

在回答其中一个问题时,有一个讨论主题below my answer。这表明取决于访问说明符(或可能是继承的类型)private/protected/publicsizeof class对象可能会有所不同!

我仍然不清楚他们的简短讨论,这怎么可能?

1 个答案:

答案 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; }; 和(ab)由访问说明符分隔,因此编译器可以自由执行此类重新排序,使

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; }; ab具有不同的访问控制权。

请注意,在C ++ 11规则下,给出了如下定义:

c

编译器必须在class Foo { char a; public: int b; protected: char c; public: int d; }; 之后放置d,即使它们被访问说明符分开。


(那就是说,我不知道任何实际利用任何标准提供的纬度的实现)