问题描述
有以下两段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行不同),为什么运行结果就不一样呢?
百思不得姐!!希望大神指点一二,谢谢。
问题解答
回答1:请注意使用所谓的初始化器的规则它们不是按照初始化器的位置来决定谁先初始化而是根据变量谁在前来决定谁先初始化。
第二段代码由于mb在前,所以mb会被先初始化。详细内容应该C++ Primer 5ed上面有的,个人的建议是不要使用互相引用来初始化
回答2:这是变量初始化顺序有关,第二段代码中mb在前所以mb先初始化而此时ma还没有初始化是个随机数,所以mb不会是3。在c++类构造函数中的变量初始化顺序只和变量定义的顺序有关,与构造函数中初始化列表的顺序无关。因为成员变量的初始化次序是根据变量在内存中次序有关,而内存中的排列顺序早在编译期就根据变量的定义次序决定了。这点在EffectiveC++中有详细介绍。
回答3:《c++ primer》(中文第 4 版) 说:构造函数初始化列表仅指定用于初始化成员的值,并不指定这些初始化执行的次序。
也就是说,你遇到的是一种未定义的行为,这依赖于编译器的具体实现。如果编译器是按照类成员出现的次序进行初始化,那么第一个例子就是正确的,而第二个例子就是错误的(因为 mb 失去了被初始化的机会)。
回答4:几位大神的回答都很好,无奈只能采纳一个答案,我给第一个先回答的大神吧