非结构对象布局

  • 本文关键字:布局 对象 结构 c++
  • 更新时间 :
  • 英文 :


我一直在阅读Lippman的" C 对象模型",我遇到了以下内容:

保证在C 中保证将按声明的顺序进行编写的数据成员。但是,多个访问部分中包含的数据布局是未定义的。

这是否意味着以下代码中的评论是正确的?

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_;
};

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

class Foo
{
public:
     Foo(): a_(1), b_(2)
     {
          // is initialization order guaranteed?
     }
private:
     int a_;
private:
     int b_;
};

此外,也许我可以在标准中阅读任何有关它的信息?

upd

我有:

class Foo
{
public:
     Foo(): a_(1), b_(2) {}
private:
     int a_;
     int b_;
};

我确定一切都很好:在初始化b_之前初始化了a_。

我有:

class Foo
{
public:
     Foo(): a_(1), b_(2) {}
public:
     int a_;
private:
     int b_;
};

据我了解,我不能确定在初始化B_之前初始化A_。

为什么?因为众所周知,初始化顺序仅由声明的顺序确定。但是在上面的Quoute中说,未指定A_(作为公共)和B_(作为私有)的声明顺序。

布局:

如您所引用的文本所述,布局取决于声明和访问控制的顺序。分配了所有具有相同访问控制的成员,以便后来声明的成员在对象中具有较高的状态。未指定具有不同访问控制的成员的顺序。请注意,这允许所有成员根据声明命令进行布局。

(非工会)类的非静态数据成员,具有相同的访问 对控制(第11条)分配,以便以后的成员具有更高的 集体对象中的地址。非静态分配的顺序 具有不同访问控制的数据成员未指定(第11条)。

N4296§9.2/13

初始化

初始化是按照成员界的顺序进行的,成员启动器的顺序(构造函数的:之后)无关紧要:

然后,非静态数据成员的初始化为 在班级定义中声明(再次 mem-intializer)。

N4296§12.6.2/13.3

访问控制无关紧要。

经验验证

#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;
}

将输出(现场在IDEONE上)

A
B
some_address
some_address + 1

解决您的编辑:

class Foo
{
public:
     Foo(): a_(1), b_(2) {}
public:
     int a_;
private:
     int b_;
};

据我了解,我不能确定在初始化B_之前初始化A_。

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

,但在上面的quoute中说,未指定A_(作为public)和b_(作为私有)的声明顺序。

报价说,未指定的a_b_的(相对)布局。这与初始化的顺序无关。

最新更新