C++對(duì)象的空間分配與初始化時(shí)機(jī)
Posted on 2012-03-10 11:55 亂78糟 閱讀(965) 評(píng)論(0) 編輯 收藏 引用 所屬分類: C語言派系C++規(guī)定,一個(gè)變量可以在程序范圍內(nèi)的任何地方定義,也就是說在這個(gè)變量定義之前編譯器是無法給它分配內(nèi)存空間的。在這點(diǎn)上和C不同,C強(qiáng)制要求變量的聲明和定義必須放在條件塊的開始。
雖然如此,但是現(xiàn)在的C++編譯器通常像C編譯器一樣,在一個(gè)程序塊的開頭就分配好所有變量的內(nèi)存。這一切對(duì)于程序員來說是透明的,因?yàn)槲覀兊淖兞吭诙x之前總是無法得到存儲(chǔ)空間,即便編譯器這么干了!
即使存儲(chǔ)空間在一開始就被分配了,但是C++對(duì)象的構(gòu)造函數(shù)仍然需要到對(duì)象定義的時(shí)候才會(huì)被調(diào)用,因?yàn)闃?biāo)識(shí)符只有到此時(shí)才是有效的。編譯器為了防止程序員用一些條件選擇手段跳過變量的初始化就開始使用,它會(huì)檢查代碼中是否把一個(gè)變量對(duì)象的定義放到了條件塊中,比如switch的case塊,goto等,看下面這段代碼:
輸入10,跳過了a的初始化,程序運(yùn)行結(jié)果同樣不可知。
雖然如此,但是現(xiàn)在的C++編譯器通常像C編譯器一樣,在一個(gè)程序塊的開頭就分配好所有變量的內(nèi)存。這一切對(duì)于程序員來說是透明的,因?yàn)槲覀兊淖兞吭诙x之前總是無法得到存儲(chǔ)空間,即便編譯器這么干了!
即使存儲(chǔ)空間在一開始就被分配了,但是C++對(duì)象的構(gòu)造函數(shù)仍然需要到對(duì)象定義的時(shí)候才會(huì)被調(diào)用,因?yàn)闃?biāo)識(shí)符只有到此時(shí)才是有效的。編譯器為了防止程序員用一些條件選擇手段跳過變量的初始化就開始使用,它會(huì)檢查代碼中是否把一個(gè)變量對(duì)象的定義放到了條件塊中,比如switch的case塊,goto等,看下面這段代碼:
1 #include <iostream>
2 #include <string>
3
4 using namespace std;
5
6 class A{
7 public:
8 //A(){} //對(duì)于VC2005和GCC來說,只有提供構(gòu)造函數(shù),編譯器才會(huì)檢測(cè)出錯(cuò)誤
9 int b;
10 };
11
12 int main()
13 {
14 int i;
15 cin>>i;
16
17 if (i < 10)
18 goto flag;
19
20 A fsd; //構(gòu)造函數(shù)的調(diào)用被goto跳過
21 fsd.b = i;
22
23 flag:
24 switch (i)
25 {
26 case 1:
27 A a;
28 a.b = 3;
29 break;
30 case 10:
31 {
32 A aa;
33 aa.b = 10;
34 cout<<a.b<<endl; //error C2360: initialization of 'a' is skipped by 'case' label
35 break;
36 }
37 default:
38 break;
39 }
40
41 cout<<fsd.b<<endl;//如果輸入?yún)?shù)小于10,那么fsd的初始化將被跳過,程序運(yùn)行到這里崩潰
42
43 return 0;
44 }
輸入1,跳過了fsd的初始化,程序運(yùn)行結(jié)果不可知。2 #include <string>
3
4 using namespace std;
5
6 class A{
7 public:
8 //A(){} //對(duì)于VC2005和GCC來說,只有提供構(gòu)造函數(shù),編譯器才會(huì)檢測(cè)出錯(cuò)誤
9 int b;
10 };
11
12 int main()
13 {
14 int i;
15 cin>>i;
16
17 if (i < 10)
18 goto flag;
19
20 A fsd; //構(gòu)造函數(shù)的調(diào)用被goto跳過
21 fsd.b = i;
22
23 flag:
24 switch (i)
25 {
26 case 1:
27 A a;
28 a.b = 3;
29 break;
30 case 10:
31 {
32 A aa;
33 aa.b = 10;
34 cout<<a.b<<endl; //error C2360: initialization of 'a' is skipped by 'case' label
35 break;
36 }
37 default:
38 break;
39 }
40
41 cout<<fsd.b<<endl;//如果輸入?yún)?shù)小于10,那么fsd的初始化將被跳過,程序運(yùn)行到這里崩潰
42
43 return 0;
44 }
輸入10,跳過了a的初始化,程序運(yùn)行結(jié)果同樣不可知。