有以下两段C++代码。第一段为:
#include<iostream>
#include<cstdlib>
using namespace std;
class Pair{
public:
Pair(int a, int b): ma(a), mb(ma+b) {}
int ma;
int mb;
};
int main(){
Pair p(1,2);
cout << p.ma << " " << p.mb << endl;
system("pause");
return 0;
}
运行结果为:
1 3
第二段代码为:
#include<iostream>
#include<cstdlib>
using namespace std;
class Pair{
public:
Pair(int a, int b): ma(a), mb(ma+b) {}
int mb;
int ma;
};
int main(){
Pair p(1,2);
cout << p.ma << " " << p.mb << endl;
system("pause");
return 0;
}
运行结果为:
1 -858993458
两段代码,仅仅是成员变量 ma、mb 的定义顺序不同(第8行、9行不同),为什么运行结果就不一样呢?
百思不得姐!!希望大神指点一二,谢谢。
高洛峰2017-04-17 13:03:01
请注意使用所谓的初始化器的规则
它们不是按照初始化器的位置来决定谁先初始化
而是根据变量谁在前来决定谁先初始化。
第二段代码由于mb在前,所以mb会被先初始化。
详细内容应该C++ Primer 5ed上面有的,个人的建议是不要使用互相引用来初始化
怪我咯2017-04-17 13:03:01
这是变量初始化顺序有关,第二段代码中mb在前所以mb先初始化而此时ma还没有初始化是个随机数,所以mb不会是3。在c++类构造函数中的变量初始化顺序只和变量定义的顺序有关,与构造函数中初始化列表的顺序无关。因为成员变量的初始化次序是根据变量在内存中次序有关,而内存中的排列顺序早在编译期就根据变量的定义次序决定了。这点在EffectiveC++中有详细介绍。
黄舟2017-04-17 13:03:01
《c++ primer》(中文第 4 版) 说:构造函数初始化列表仅指定用于初始化成员的值,并不指定这些初始化执行的次序。
也就是说,你遇到的是一种未定义的行为,这依赖于编译器的具体实现。如果编译器是按照类成员出现的次序进行初始化,那么第一个例子就是正确的,而第二个例子就是错误的(因为 mb
失去了被初始化的机会)。