定義沒有初始化式的變量時,系統有時候會幫我們初始化變量。系統如何初始化取決於變量的類型以及變量定義的位置。
內置類型變量是否自動初始化取決於變量定義的位置。函數體外定義的變量初始成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未被自動初始化。
類類型變量在定義時,如果沒有提供初始化式,則會自動調用默認構造函數進行初始化(不論變量在哪裡定義)。如果某類型沒有默認構造函數,則定義該類型對象時必須提供顯示初始化式。
一段簡單的測試代碼(默認構造函數由編譯器自動生成):
#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”: 沒有合適的默認構造函數可用。