微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

原文地址:https://www.jb51.cc/c/112294.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐