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

在回答其中一个问题时,有一个讨论话题 below my answer.这表明根据访问说明符(或可能是继承类型)private / protected / public,类对象的sizeof可能会有所不同!

我仍然从他们的简短的讨论中看不懂,怎么可能呢?

解决方法

注意下面C11的新语言

在C 03中,有语言使之成为可能,9.2 [class.mem] / 12(强调我的):

Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). 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).

所以给出这个定义:

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)对齐的系统上,编译器不允许在b之前重新排序c,强制在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.

在C11中,语言略有变化. N3485 9.2 [class.mem] / 13说(强调我的):

Nonstatic data members of a (non-union) class with the same access control (Clause 11) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (Clause 11). 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).

这意味着在C 11中,在上面的例子中(由3个公开分隔),编译器仍然不允许执行重新排序.它必须是这样的东西

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之后,即使它们被访问说明符分隔.

(也就是说,我不知道实际上利用了两种标准提供的纬度)

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...