1. 程式人生 > >[基礎知識]1.C++成員變數的初始化順序?

[基礎知識]1.C++成員變數的初始化順序?

下列程式的執行結果分別是?

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

相關知識點:

  1. 初始化資料成員的兩種方法:賦值法、列表法
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){}
  1. 成員變數的初始化順序
    2.1 賦值法初始化順序與建構函式中的成員變數的賦值順序有關,與成員變數的定義順序無關。
    2.2 列表法初始化順序與建構函式外的成員變數的定義順序
    有關,與初始化成員列表的順序無關。
  2. const修飾的資料成員、引用型別的資料成員只能用初始化成員列表來初始化資料,不允許用賦值語句直接賦值。
  3. 成員變數在定義時不能初始化。
  4. static成員變數必須在類外初始化,而且應在定義物件之前進行。
  5. static成員變數屬於類物件的集合,而不屬於某一個物件。無論建立多少個類的物件,都只有一個靜態資料成員的拷貝。從而實現了同一個類的不同物件之間的資料共享。
  6. 變數的初始化順序:基類的靜態變數或全域性變數->派生類的靜態變數或全域性變數->基類的成員變數->派生類的成員變數

擴充套件:

  1. 建構函式是一種特殊的成員函式,主要用於為物件分配空間,進行初始化.
  2. 建構函式沒有返回值。(不能說明為void型別
  3. 建構函式不能為虛擬函式。
  4. 建構函式的初始化順序:
    首先,任何虛基類的建構函式按照它們被繼承的順序構造;
    其次,任何非虛基類的建構函式按照它們被繼承的順序構造;
    最後,任何成員物件的建構函式按照它們宣告的順序呼叫。
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.

參考文章
C++成員變數的初始化順序問題
C++成員變數、建構函式的初始化順序