C++中變數預設初始化規則
轉載連結地址:http://www.cnblogs.com/FoxShark/p/5802239.html
定義沒有初始化式的變數時,系統有時候會幫我們初始化變數。系統如何初始化取決於變數的型別以及變數定義的位置。
1、內建型別變數是否自動初始化取決於變數定義的位置。函式體外定義的變數初始成0;函式體內定義的變數不進行自動初始化。除了用作賦值操作的左運算元,其他任何使用未初始化變數的行為都是未定義的,不要依賴未定義行為。
以int型別為例,一段簡單的測試程式碼:
#include <iostream>
using namespace std;
int a;
int main()
{
int b;
cout << a << endl;
cout << b << endl;
return 0;
}
在VS執行這段程式碼,輸出變數a的值0,同時VS會報錯:Run-Time Check Failure #3 — The variable ‘b’ is being used without being initialized。 變數a被自動初始化為0;變數b未被自動初始化。
2、類型別變數在定義時,如果沒有提供初始化式,則會自動呼叫預設建構函式進行初始化(不論變數在哪裡定義)。如果某型別沒有預設建構函式,則定義該型別物件時必須提供顯示初始化式。
一段簡單的測試程式碼(預設建構函式由編譯器自動生成):
#include <iostream>
using namespace std;
class testA
{
public:
void printf() const
{
cout << data << endl;
}
private:
int data;
};
testA a;
int main()
{
testA b;
a.printf();
b.printf ();
return 0;
}
在VS執行這段程式碼,得到以下結果:
編譯器自動生成的預設建構函式使用與變數初始化相同的規則來初始化資料成員。物件a在函式體外定義,其int型別資料成員被初始為0;物件b在函式體內定義,合成預設建構函式不會對其進行初始化(符合內建型別變數初始化規則),其中存放的都是隨機值。同樣,如果資料成員是類型別,則會呼叫相應的預設建構函式對資料成員進行初始化。
如果稍微改變一下這個類的定義,定義一個建構函式以阻止編譯器自動生成預設建構函式:
#include <iostream>
using namespace std;
class testA
{
public:
testA(int a)
{
data = a;
}
void printf() const
{
cout << data << endl;
}
private:
int data;
};
testA a;
int main()
{
testA b;
a.printf();
b.printf();
return 0;
}
這段程式碼無法通過編譯:error C2512: “testA”: 沒有合適的預設建構函式可用。
定義陣列時,如果沒有顯示提供初始化列表,則陣列元素的自動化初始規則同普通變數一樣:函式體外定義的內建型別陣列,其元素初始為0;函式體內定義的內建型別陣列,其元素無初始化;類型別陣列無論在哪裡定義,皆呼叫預設建構函式進行初始化,無預設建構函式則必須提供顯示初始化列表。
如果定義陣列時,僅提供了部分元素的初始列表,其剩下的陣列元素,若是類型別則呼叫預設建構函式進行初始,若是內建型別則初始為0(不論陣列定義位置)。
對於動態分配的陣列,如果陣列元素是內建型別,其元素無初始化;如果陣列元素是類型別,依然呼叫預設建構函式進行初始化。也可以在使用跟在陣列長度後面的一對空圓括號對陣列元素做值初始化。
例如: int *ptrA = new int[10];
int *ptrB = new int[10] ();
其中ptrA指向的動態陣列其元素未初始化,而ptrB指向的動態陣列元素被初始化為0。
3、對於動態分配的單個物件,可使用直接初始化的語法規則在定義時顯示初始化。如果不提供顯示初始化式,動態建立的物件與在函式內部定義的變數初始化方式相同(即:內建型別無初始化,類型別呼叫預設建構函式進行初始化)。