我一直在阅读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_
的(相对)布局。这与初始化的顺序无关。