所有旧的和现代的C ++书籍和专家都声明按照声明顺序初始化类成员。但是,如果我不这样做,也没有解释? 我不是在谈论有const类型成员或smth的类。只是简单的类。
考虑样本:
class A
{
int n;
std::vector<double> VD;
char c;
public:
A():
VD(std::vector<double>(3)),
c('a'),
n(44)
{
}
};
编写的代码与声明它们的顺序相同的是什么?
答案 0 :(得分:6)
编写的代码与声明它们的顺序相同的是什么?
如果成员不依赖于彼此的初始化顺序,则没有任何区别。但如果他们这样做,那么成员初始化列表可能会说谎。
许多程序员被他们咬了,当他们认为他们的构造函数写得正确时,但实际上他们手上有不确定的行为。
考虑这个简单的案例:
struct foo {
int _a;
int _b;
foo(int b) : _b(b), _a(2 * _b) {}
};
上例中的_a
是什么?如果您回答&#34;之后的行为未定义,因为_b
已初始化&#34; ,那么您就错了。
答案 1 :(得分:6)
但是,如果我不这样做,也没有解释什么?
程序员无法控制它:在初始化列表中列出成员的顺序对初始化的实际顺序没有影响。编译器忽略列表中项目的顺序,并重新排序表达式以匹配声明顺序。
这是一个简短的例子来说明这一点:
struct Foo {
Foo(const char *s) { cout << "Init " << s << endl; }
};
struct Bar {
Foo a;
Foo b;
Foo c;
Bar() : c("c"), b("b"), a("a") {
}
};
以上打印
Init a
Init b
Init c
即使初始化按相反顺序列出项目。
答案 2 :(得分:4)
生成的装配应该完全没有区别,尽管&#34; as-if&#34;规则可能会妨碍。
至少在概念上,n
在c
之前初始化。
答案 3 :(得分:3)
您无法更改初始化顺序 - 这是成员在课程中出现的顺序 - 初始化列表中的顺序并不重要,但编译器可能会警告这两个订单是否匹配。
答案 4 :(得分:0)
我认为有两个理由可以正确地订购它们。
答案 5 :(得分:0)
这取决于成员的使用方式。如果存在依赖关系,则必须遵循订单。
请考虑以下示例。
class x{
size_t n;
char * ch; // the size of dynamic char array depends on n
}
此处,以不同顺序初始化将导致未定义的行为
除了这个原因,当然可读性和一致性对编码指南POV很重要。