首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非结构化对象布局

非结构化对象布局
EN

Stack Overflow用户
提问于 2016-12-06 09:19:04
回答 1查看 57关注 0票数 0

我一直在阅读利普曼的“在C++对象模型中”,我遇到了以下情况:

单个访问部分中的数据成员保证在C++中按照声明的顺序排列。但是,包含在多个访问节中的数据的布局仍未定义。

这是否意味着下面代码中的注释是正确的?

代码语言:javascript
复制
class Foo
{
public:
     Foo(): a_(1), b_(2), c_(3)
     {
          // it does not matter that the order of a_, b_, c_ is the same in class definition and in initialization list, we do not know which one will be initialized first?
     }

public:
     int a_;

private:
     int b_;

protected:
     int c_;
};

如果是真的,那么几个包含成员组的私有部分又如何呢?

代码语言:javascript
复制
class Foo
{
public:
     Foo(): a_(1), b_(2)
     {
          // is initialization order guaranteed?
     }

private:
     int a_;

private:
     int b_;
};

另外,也许我能在标准里读到关于它的任何东西?

UPD

当我有:

代码语言:javascript
复制
class Foo
{
public:
     Foo(): a_(1), b_(2) {}
private:
     int a_;
     int b_;
};

我确信一切正常:在初始化a_之前初始化b_。

当我有:

代码语言:javascript
复制
class Foo
{
public:
     Foo(): a_(1), b_(2) {}
public:
     int a_;
private:
     int b_;
};

据我所知,在初始化a_之前,我无法确定是否初始化了b_。

为什么?因为,正如我们所知道的,初始化的顺序是由声明的顺序决定的。但是在上面的引文中,a_ (作为公共的)和b_ (作为私有的)的声明顺序是没有具体说明的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-06 09:43:20

布局:

正如您引用的文本中所述,布局取决于声明的顺序和访问控制。分配具有相同访问控制的所有成员,以便以后声明的成员在对象中具有更高的值。不指定具有不同访问控制的成员的顺序。请注意,这使得所有成员都可以按照声明顺序进行布局。

分配具有相同访问控制(第11条)的(非联合)类的非静态数据成员,以便以后的成员在类对象中具有更高的地址。具有不同访问控制的非静态数据成员的分配顺序未指定(第11条)。 N4296§9.2/13

初始化

初始化按照成员删除的顺序进行,成员初始化的顺序(在构造函数的:之后)并不重要:

然后,按照类定义中声明的顺序初始化非静态数据成员(同样不考虑mem初始化器的顺序)。 N4296§12.6.2/13.3

访问控制并不重要。

经验验证

代码语言:javascript
复制
#include <iostream>
using std::cout;
using std::endl;

struct A
{
    A()
    {
        cout << "A" << endl;
    }
};

struct B
{
    B()
    {
        cout << "B" << endl;
    }
};

struct X
{
    A a;
    B b;
    X() : b(), a() {}
};

int main() {
    X x;
    cout << "a @ " << &(x.a) << endl;
    cout << "b @ " << &(x.b) << endl;
    return 0;
}

威尔输出(以理想为生)

代码语言:javascript
复制
A
B
some_address
some_address + 1

寻址您的编辑:

代码语言:javascript
复制
class Foo
{
public:
     Foo(): a_(1), b_(2) {}
public:
     int a_;
private:
     int b_;
};

据我所知,在初始化a_之前,我无法确定是否初始化了b_。

是的,您可以确保a_是在b_之前初始化的。这是标准所保证的。

但是在上面的引文中,a_ (作为公共的)和b_ (作为私有的)的声明顺序是没有具体说明的。

引用中说,a_b_内存中的(相对)布局未指定。这与初始化的顺序无关。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40991729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档