使用一段簡單的**說明這個問題:
using system; using system.collections.generic; using system.linq; using system.text; namespace staticvar } //例子1 class common1 class common2 class myclassa ",a); } public void outputa(int a) ",a); } } class myclassb ",b); } public void outputb(int b) ",b); } } //例子2 class common3 class myclassc } //例子3 class common4 class myclassd public void outputd() } class myclasse public void outpute() } }
(實驗一)
1)如果去掉第14行common1.objb1.outputb(3); 前面的注釋,看一下程式的執行結果:
a引數構造 1
b引數構造 1
主函式開始執行
b輸出 3
2)如果去掉第15行的common2.obja2.outputa(4);前面的注釋,看一下程式執行結果:
a引數構造 2
b引數構造 2
主函式開始執行
a輸出 4
3)第14,15行注釋都去掉,程式執行結果:
a引數構造 1
b引數構造 1
a引數構造 2
b引數構造 2
主函式開始執行
b輸出 3
a輸出 4
可以看到:
1)如果某個靜態物件的構造是在main()函式之外,而在main()函式內使用了該物件,那麼該物件的構造會發生在main()函式執行之前
2)如果某個靜態物件a在main()函式之外的某個類b中被構造,而在main()函式之中使用了a,那麼在b中所有使用建構函式初始化的靜態物件(無論他們在main()函式中是否出現),他們會按照在b中出現的先後順序被構造。
3)如果main()之外的某個類a中定義了靜態物件的構造,但是這些靜態物件都沒有在main()函式中出現過,那麼他們的建構函式不會被執行
4)如果靜態物件a的構造出現在main()函式之外的common1類,靜態物件b的構造出現在main()之外的common2類中,a和b先後出現在main()函式之中,那麼common1和common2中靜態物件被構造的執行順序是:先a後b,即與main()函式中出現的順序一致。
(實驗二)
去掉第17行**common3.objc = new myclassc();的注釋,程式執行結果:
主函式開始執行
c構造結論:靜態成員在main()函式之外的某個類中只給出定義,是不會在該類中被構造的。
(實驗三)
去掉19行common4.objd.outputd();的注釋,程式執行結果如下:
e構造d構造
e輸出主函式開始執行
d輸出但是,如果把class common4中的88,89兩行交換順序,程式執行就會發生錯誤。原因如下:main()函式中使用了靜態物件objd,該物件的定義在類common4當中,那麼首先就要順序執行common4中給出了建構函式的靜態成員的建構函式,交換後首先執行"public static myclassd objd = new myclassd();",在objd的建構函式中又會執行"common4.obje.outpute();",但是這時候obje還沒有被構造,要想使用它就要在它所在的common4中按照給出建構函式的靜態成員的先後順序開始執行構造,那就要從objd開始,於是陷入了死迴圈了。
C 建構函式的執行順序
類的大小 1 一般情況下,類的大小是類裡資料成員大小之和,普通函式不佔空間 2 static不佔空間大小 3 virtual虛函式,如果有虛函式,則多乙個vptr 虛指標 不管有多少虛函式,都只有乙個虛指標,指標佔4個位元組大小。4 空類佔乙個位元組大小。建構函式的執行順序 class test t...
建構函式的執行順序
任何建構函式都可以進行配置,以便在執行自己的 前呼叫其它建構函式。我們首先看看在建立類的例項時會發生什麼情況。為了例項化派生的類,必須例項化它的基類。而要例項化這個基類,又必須例項化這個基類的基類,這樣一直例項化到system.object為止。結果是無論使用什麼建構函式例項化乙個類,總是要先呼叫s...
建構函式的執行順序
1 using system 2 using system.collections.generic 3 using system.linq 4 using system.text 5 6 namespace 例項構造器13 14 public string b bjq 15 16 public a ...