1. 程式人生 > >C++類成員變數初始化順序問題

C++類成員變數初始化順序問題

今天在看劍指offer這本書時,看待一個簡單的舉例,說應聘C++崗位的不知道成員變數初始化順序!我很驚訝,因為我也不知道,所以就看上網查了一下,看到了一個部落格()以及其中的內容,現在將我的學習過程分享出來!

首先看一下程式碼:

#include <iostream>
using namespace std;

class A
{
public:
	A()
		:n2(0),
		n1(n2 + 2)
	{}

	//~A();

	void print()
	{
		cout << "n1:" << n1 << " ,  n2:" << n2 << endl;
	}

private:
	int n1;
	int n2;
};

//A::~A()
//{
//}

int main()
{
	A a;
	a.print();
	system("pause");
	return 0;
}
大家預測一下結果,在沒執行的時候,我想大多數不懂初始化成員列表的順序的人都會和我一樣認為輸出的是:n1:2  ,  n2:0 

然而執行之後,我的電腦執行結果如下

看來我們錯了,我查詢了一下知識點,得到的結果是:

成員變數在使用初始化列表初始化時,與建構函式中初始化成員列表的順序無關,只與定義成員變數的順序有關。因為成員變數的初始化次序是根據變數在記憶體中次序有關,而記憶體中的排列順序早在編譯期就根據變數的定義次序決定了。

現在我們試試用建構函式進行測試,程式碼如下:

#include <iostream>
using namespace std;

class A
{
public:
	//A()
	//	:n2(0),
	//	n1(n2 + 2)
	//{}

	A()
	{
		n2 = 0;
		n1 = n2 + 2;
	}

	//~A();

	void print()
	{
		cout << "n1:" << n1 << " ,  n2:" << n2 << endl;
	}

private:
	int n1;
	int n2;
};

//A::~A()
//{
//}

int main()
{
	A a;
	a.print();
	system("pause");
	return 0;
}
結果如下:


這個結果又表明:

如果不使用初始化列表初始化,在建構函式內初始化時,此時與成員變數在建構函式中的位置有關。

接下來我又測試了const 成員變數和static成員變數,

當const成員變數在建構函式中初始化時,程式碼如下:

#include <iostream>
using namespace std;

class A
{
public:
	//A()
	//	:n2(0),
	//	n1(n2 + 2)
	//{}

	A()
	{
		n2 = 0;
		n1 = n2 + 2;
		n3 = 4;
		n4 = 5;
	}

	//~A();

	void print()
	{
		cout << "n1:" << n1 << " ,  n2:" << n2 << "n3:" << n3 << " ,  n4:" << n4 << endl;
	}

private:
	int n1;
	int n2;
	const int n3;
	static int n4;
};

//A::~A()
//{
//}

int main()
{
	A a;
	a.print();
	system("pause");
	return 0;
}
有錯誤,執行時報告的錯誤列表如下: 將在建構函式中初始化變成在初始化列表中初始化,程式碼如下:
	A()
		: n2(0),
		n1(n2 + 2),
	n3(4),
	n4(5)
	{}
然而結果又有錯誤,錯誤如下: 上邊兩次試驗說明:

類中const成員常量必須在建構函式初始化列表中初始化。

類中static成員變數,不能在類內初始化。

編輯程式碼測試,程式碼如下:
#include <iostream>
using namespace std;

class A
{
public:
	A()
	<span style="white-space:pre">	</span>:n3(4)
	{
		n2 = 0;
		n1 = n2 + 2;
	}

	void print()
	{
		cout << "n1:" << n1 << " ,  n2:" << n2 << " ,  n3:" << n3 << endl;
	}
	int Getn4()
	{
		n4 += 5;
		return n4;
	}
public:
	static int n4;
private:
	int n1;
	int n2;
	const int n3;

};
int A::n4 = 3;     <span style="white-space:pre">	</span>//必須這樣初始化

int main()
{
	A a;
	cout << "A:n4: " << A::n4 << endl;
	A::n4 = 7;  <span style="white-space:pre">	</span>//必須這樣賦值或者通過成員函式
	a.print();
	cout << "A:n4: " << A::n4 << endl;
	a.Getn4();<span style="white-space:pre">	</span>
	cout << "A:n4: " << A::n4 << endl;
	system("pause");
	return 0;
}
結果如下: 介紹一下靜態變數:

靜態成員是類所有的物件的共享的成員,而不是某個物件的成員。它在物件中不佔用儲存空間,這個屬性為整個類所共有,不屬於任何一個具體物件。所以靜態成員不能在類的內部初始化,比如宣告一個學生類,其中一個成員為學生總數,則這個變數就應當宣告為靜態變數,應該根據實際需求來設定成員變數。

下面列出總結:

1.成員變數在使用初始化列表初始化時,與建構函式中初始化成員列表的順序無關,只與定義成員變數的順序有關。

2.如果不使用初始化列表初始化,在建構函式內初始化時,此時與成員變數在建構函式中的位置有關。

3.類中const成員常量必須在建構函式初始化列表中初始化。

4.類中static成員變數,只能在類內外初始化(同一類的所有例項共享靜態成員變數)。

下面是C++類成員變數初始化順序:

  • 1) 基類的靜態變數或全域性變數
  • 2) 派生類的靜態變數或全域性變數
  • 3) 基類成員變數
  • 4) 派生類的成員變數
謝謝各位批評指正!!!