[基礎知識]1.C++成員變數的初始化順序?
阿新 • • 發佈:2019-01-09
下列程式的執行結果分別是?
class A
{
private:
int n1;
int n2;
public:
A():n2(0),n1(n2+2019){}
void Print(){
cout << "n1:" << n1 << ", n2:" << n2 << endl;
}
};
int main()
{
A a;
a.Print();
return 0;
}
class B
{
private:
int n1;
int n2;
public:
B(){
n2 = 0;
n1 = n2 + 2019;
}
void Print(){
cout << "n1:" << n1 << ", n2:" << n2 << endl;
}
};
int main()
{
B b;
b.Print();
return 0;
}
- 答案:
A. n1:隨機數, n2:0
B. n1:2019, n2:0
相關知識點:
- 初始化資料成員的兩種方法:賦值法、列表法
class Complex{
private:
double real;
double image;
public:
Complex(double r, double i); // 宣告建構函式原型
...
};
/* 用賦值語句對資料成員賦初值 */
Complex::Complex(double r, double i){
real = r;
imag = i;
}
/* 用成員初始化列表對資料成員初始化 */
Complex::Complex(double r, double i):real(r),imag(i){}
- 成員變數的初始化順序
2.1 賦值法初始化順序與建構函式中的成員變數的賦值順序有關,與成員變數的定義順序無關。
2.2 列表法初始化順序與建構函式外的成員變數的定義順序 - 用const修飾的資料成員、引用型別的資料成員只能用初始化成員列表來初始化資料,不允許用賦值語句直接賦值。
- 成員變數在定義時不能初始化。
- static成員變數必須在類外初始化,而且應在定義物件之前進行。
- static成員變數屬於類物件的集合,而不屬於某一個物件。無論建立多少個類的物件,都只有一個靜態資料成員的拷貝。從而實現了同一個類的不同物件之間的資料共享。
- 變數的初始化順序:基類的靜態變數或全域性變數->派生類的靜態變數或全域性變數->基類的成員變數->派生類的成員變數
擴充套件:
- 建構函式是一種特殊的成員函式,主要用於為物件分配空間,進行初始化.
- 建構函式沒有返回值。(不能說明為void型別)
- 建構函式不能為虛擬函式。
- 建構函式的初始化順序:
首先,任何虛基類的建構函式按照它們被繼承的順序構造;
其次,任何非虛基類的建構函式按照它們被繼承的順序構造;
最後,任何成員物件的建構函式按照它們宣告的順序呼叫。
class OBJ1{
public:
OBJ1(){ cout<<"OBJ1\n"; }
};
class OBJ2{
public:
OBJ2(){ cout<<"OBJ2\n";}
}
class Base1{
public:
Base1(){ cout<<"Base1\n";}
}
class Base2{
public:
Base2(){ cout <<"Base2\n"; }
};
class Base3{
public:
Base3(){ cout <<"Base3\n"; }
};
class Base4{
public:
Base4(){ cout <<"Base4\n"; }
};
// 繼承順序
class Derived :public Base1, virtual public Base2,public Base3, virtual public Base4{
public:
// 初始化列表
Derived() :Base4(), Base3(), Base2(),Base1(), obj2(), obj1(){
cout <<"Derived ok.\n";
}
protected:
// 宣告順序
OBJ1 obj1;
OBJ2 obj2;
};
int main()
{
Derived aa; // 初始化
cout <<"This is ok.\n";
return 0;
}
- 執行結果:
Base2 // 虛擬基類按照被繼承順序初始化
Base4 // 虛擬基類按照被繼承的順序
Base1 // 非虛擬基類按照被繼承的順序初始化
Base3 // 非虛擬基類按照被繼承的順序
OBJ1 // 成員函式按照宣告的順序初始化
OBJ2 // 成員函式按照宣告的順序
Derived ok.
This is ok.