我一直在阅读利普曼的“在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_;
};我确信一切正常:在初始化a_之前初始化b_。
当我有:
class Foo
{
public:
Foo(): a_(1), b_(2) {}
public:
int a_;
private:
int b_;
};据我所知,在初始化a_之前,我无法确定是否初始化了b_。
为什么?因为,正如我们所知道的,初始化的顺序是由声明的顺序决定的。但是在上面的引文中,a_ (作为公共的)和b_ (作为私有的)的声明顺序是没有具体说明的。
发布于 2016-12-06 09:43:20
布局:
正如您引用的文本中所述,布局取决于声明的顺序和访问控制。分配具有相同访问控制的所有成员,以便以后声明的成员在对象中具有更高的值。不指定具有不同访问控制的成员的顺序。请注意,这使得所有成员都可以按照声明顺序进行布局。
分配具有相同访问控制(第11条)的(非联合)类的非静态数据成员,以便以后的成员在类对象中具有更高的地址。具有不同访问控制的非静态数据成员的分配顺序未指定(第11条)。 N4296§9.2/13
。
初始化
初始化按照成员删除的顺序进行,成员初始化的顺序(在构造函数的:之后)并不重要:
然后,按照类定义中声明的顺序初始化非静态数据成员(同样不考虑mem初始化器的顺序)。 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;
}威尔输出(以理想为生)
A
B
some_address
some_address + 1寻址您的编辑:
class Foo
{
public:
Foo(): a_(1), b_(2) {}
public:
int a_;
private:
int b_;
};据我所知,在初始化a_之前,我无法确定是否初始化了b_。
是的,您可以确保a_是在b_之前初始化的。这是标准所保证的。
但是在上面的引文中,a_ (作为公共的)和b_ (作为私有的)的声明顺序是没有具体说明的。
引用中说,a_和b_内存中的(相对)布局未指定。这与初始化的顺序无关。
https://stackoverflow.com/questions/40991729
复制相似问题