有以下两段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
失去了被初始化的機會)。