成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C#析構(gòu)函數(shù)和C#構(gòu)造函數(shù)的用法

開發(fā) 后端
C#構(gòu)造函數(shù)與C#析構(gòu)函數(shù)是一個(gè)類中看似較為簡單的兩類函數(shù),但在實(shí)際運(yùn)用過程中總會(huì)出現(xiàn)一些意想不到的運(yùn)行錯(cuò)誤。本文將較系統(tǒng)的介紹構(gòu)造函數(shù)與析構(gòu)函數(shù)的原理及在C#中的運(yùn)用,以及在使用過程中需要注意的若干事項(xiàng)。

一.C#構(gòu)造函數(shù)與C#析構(gòu)函數(shù)的原理

作為比C更先進(jìn)的語言,C#提供了更好的機(jī)制來增強(qiáng)程序的安全性。C#編譯器具有嚴(yán)格的類型安全檢查功能,它幾乎能找出程序中所有的語法問題,這的確幫了程序員的大忙。但是程序通過了編譯檢查并不表示錯(cuò)誤已經(jīng)不存在了,在“錯(cuò)誤”的大家庭里,“語法錯(cuò)誤”的地位只能算是冰山一角。級別高的錯(cuò)誤通常隱藏得很深,不容易發(fā)現(xiàn)。

根據(jù)經(jīng)驗(yàn),不少難以察覺的程序錯(cuò)誤是由于變量沒有被正確初始化或清除造成的,而初始化和清除工作很容易被人遺忘。微軟利用面向?qū)ο蟮母拍钤谠O(shè)計(jì)C#語言時(shí)充分考慮了這個(gè)問題并很好地予以解決:把對象的初始化工作放在構(gòu)造函數(shù)中,把清除工作放在析構(gòu)函數(shù)中。當(dāng)對象被創(chuàng)建時(shí),構(gòu)造函數(shù)被自動(dòng)執(zhí)行。當(dāng)對象消亡時(shí),析構(gòu)函數(shù)被自動(dòng)執(zhí)行。這樣就不用擔(dān)心忘記對象的初始化和清除工作。

二.C#構(gòu)造函數(shù)的運(yùn)用

構(gòu)造函數(shù)的名字不能隨便起,必須讓編譯器認(rèn)得出才可以被自動(dòng)執(zhí)行。它的命名方法既簡單又合理:讓構(gòu)造函數(shù)與類同名。除了名字外,構(gòu)造函數(shù)的另一個(gè)特別之處是沒有返回值類型,這與返回值類型為void的函數(shù)不同。如果它有返回值類型,那么編譯器將不知所措。在你可以訪問一個(gè)類的方法、屬性或任何其它東西之前, 第一條執(zhí)行的語句是包含有相應(yīng)類的構(gòu)造函數(shù)。甚至你自己不寫一個(gè)構(gòu)造函數(shù),也會(huì)有一個(gè)缺省構(gòu)造函數(shù)提供給你。

  1. class TestClass  
  2. {  
  3. public TestClass(): base() {} // 由CLR提供  
  4. }   

下面列舉了幾種類型的構(gòu)造函數(shù)

1)缺省構(gòu)造函數(shù)

  1. class TestClass  
  2. {  
  3. public TestClass(): base() {}   
  4. }  

上面已介紹,它由系統(tǒng)(CLR)提供。

2)實(shí)例構(gòu)造函數(shù)

實(shí)例構(gòu)造函數(shù)是實(shí)現(xiàn)對類中實(shí)例進(jìn)行初始化的方法成員。如:

  1. using System;  
  2. class Point  
  3. {  
  4. public double x, y;  
  5. public Point()   
  6. {  
  7. this.x = 0;  
  8. this.y = 0;  
  9. }  
  10.  
  11. public Point(double x, double y)  
  12. {  
  13. this.x = x;  
  14. this.y = y;  
  15. }  
  16. …  
  17. }  
  18.  
  19. class Test  
  20. {  
  21. static void Main()   
  22. {  
  23. Point a = new Point();  
  24. Point b = new Point(3, 4); // 用構(gòu)造函數(shù)初始化對象  
  25. …  
  26. }  
  27. }  

聲明了一個(gè)類Point,它提供了兩個(gè)構(gòu)造函數(shù)。它們是重載的。一個(gè)是沒有參數(shù)的Point構(gòu)造函數(shù)和一個(gè)是有兩個(gè)double參數(shù)的Point構(gòu)造函數(shù)。如果類中沒有提供這些構(gòu)造函數(shù),那么會(huì)CLR會(huì)自動(dòng)提供一個(gè)缺省構(gòu)造函數(shù)的。但一旦類中提供了自定義的構(gòu)造函數(shù),如Point()和Point(double x, double y),則缺省構(gòu)造函數(shù)將不會(huì)被提供,這一點(diǎn)要注意。

3) 靜態(tài)構(gòu)造函數(shù)

靜態(tài)構(gòu)造函數(shù)是實(shí)現(xiàn)對一個(gè)類進(jìn)行初始化的方法成員。它一般用于對靜態(tài)數(shù)據(jù)的初始化。靜態(tài)構(gòu)造函數(shù)不能有參數(shù),不能有修飾符而且不能被調(diào)用,當(dāng)類被加載時(shí),類的靜態(tài)構(gòu)造函數(shù)自動(dòng)被調(diào)用。如:

  1. using System.Data;  
  2. class Employee  
  3. {  
  4. private static DataSet ds;  
  5. static Employee()  
  6. {  
  7. ds = new DataSet(...);  
  8. }  
  9. ...  
  10. }  

聲明了一個(gè)有靜態(tài)構(gòu)造函數(shù)的類Employee。注意靜態(tài)構(gòu)造函數(shù)只能對靜態(tài)數(shù)據(jù)成員進(jìn)行初始化,而不能對非靜態(tài)數(shù)據(jù)成員進(jìn)行初始化。但是,非靜態(tài)構(gòu)造函數(shù)既可以對靜態(tài)數(shù)據(jù)成員賦值,也可以對非靜態(tài)數(shù)據(jù)成員進(jìn)行初始化。

如果類僅包含靜態(tài)成員,你可以創(chuàng)建一個(gè)private的構(gòu)造函數(shù):private TestClass() {…},但是private意味著從類的外面不可能訪問該構(gòu)造函數(shù)。所以,它不能被調(diào)用,且沒有對象可以被該類定義實(shí)例化。

以上是幾種類型構(gòu)造函數(shù)的簡單運(yùn)用,下面將重點(diǎn)介紹一下在類的層次結(jié)構(gòu)中(即繼承結(jié)構(gòu)中)基類和派生類的構(gòu)造函數(shù)的使用方式。派生類對象的初始化由基類和派生類共同完成:基類的成員由基類的構(gòu)造函數(shù)初始化,派生類的成員由派生類的構(gòu)造函數(shù)初始化。

當(dāng)創(chuàng)建派生類的對象時(shí),系統(tǒng)將會(huì)調(diào)用基類的構(gòu)造函數(shù)和派生類的構(gòu)造函數(shù),構(gòu) 造函數(shù)的執(zhí)行次序是:先執(zhí)行基類的構(gòu)造函數(shù),再執(zhí)行派生類的構(gòu)造函數(shù)。如果派生類又有對象成員,則,先執(zhí)行基類的構(gòu)造函數(shù),再執(zhí)行成員對象類的構(gòu)造函數(shù),最后執(zhí)行派生類的構(gòu)造函數(shù)。

至于執(zhí)行基類的什么構(gòu)造函數(shù),缺省情況下是執(zhí)行基類的無參構(gòu)造函數(shù),如果要執(zhí)行基類的有參構(gòu)造函數(shù),則必須在派生類構(gòu)造函數(shù)的成員初始化表中指出。如:

  1. class A  
  2. private int x;  
  3. public A( ) { x = 0; }  
  4. public A( int i ) { x = i; }  
  5. };  
  6.  
  7. class B : A  
  8. private int y;  
  9. public B( ) { y = 0; }  
  10. public B( int i ) { y = i; }  
  11. public B( int i, int j ):A(i) { y = j; }  
  12. };  
  13.  
  14. B b1 = new B(); //執(zhí)行基類A的構(gòu)造函數(shù)A(),再執(zhí)行派生類的構(gòu)造函數(shù)B()  
  15. B b2 = new B(1); //執(zhí)行基類A的構(gòu)造函數(shù)A(),再執(zhí)行派生類的構(gòu)造函數(shù)B(int)  
  16. B b3 = new B(0,1); //執(zhí)行執(zhí)行基類A的構(gòu)造函數(shù)A(int) ,再執(zhí)行派生類的 

構(gòu)造函數(shù)B(int,int)

在這里構(gòu)造函數(shù)的執(zhí)行次序是一定要分析清楚的。另外,如果基類A中沒有提供無參構(gòu)造函數(shù)public A( ) { x = 0; },則在派生類的所有構(gòu)造函數(shù)成員初始化表中必須指出基類A的有參構(gòu)造函數(shù)A(i),如下所示:

  1. class A  
  2. private int x;  
  3. public A( int i ) { x = i; }  
  4. };  
  5.  
  6. class B : A  
  7. private int y;  
  8. public B():A(i) { y = 0; }  
  9. public B(int i):A(i) { y = i; }  
  10. public B(int i, int j):A(i) { y = j; }  
  11. };  

三.C#析構(gòu)函數(shù)和垃圾回收器的運(yùn)用

析構(gòu)函數(shù)是實(shí)現(xiàn)銷毀一個(gè)類的實(shí)例的方法成員。析構(gòu)函數(shù)不能有參數(shù),不能任何修飾符而且不能被調(diào)用。由于析構(gòu)函數(shù)的目的與構(gòu)造函數(shù)的相反,就加前綴‘~’以示區(qū)別。

雖然C#(更確切的說是CLR)提供了一種新的內(nèi)存管理機(jī)制---自動(dòng)內(nèi)存管理機(jī)制(Automatic memory management),資源的釋放是可以通過“垃圾回收器” 自動(dòng)完成的,一般不需要用戶干預(yù),但在有些特殊情況下還是需要用到析構(gòu)函數(shù)的,如在C#中非托管資源的釋放。

資源的釋放一般是通過"垃圾回收器"自動(dòng)完成的,但具體來說,仍有些需要注意的地方:

1. 值類型和引用類型的引用其實(shí)是不需要什么"垃圾回收器"來釋放內(nèi)存的,因?yàn)楫?dāng)它們出了作用域后會(huì)自動(dòng)釋放所占內(nèi)存,因?yàn)樗鼈兌急4嬖跅?Stack)中;

2. 只有引用類型的引用所指向的對象實(shí)例才保存在堆(Heap)中,而堆因?yàn)槭且粋€(gè)自由存儲空間,所以它并沒有像"棧"那樣有生存期("棧"的元素彈出后就代表生存期結(jié)束,也就代表釋放了內(nèi)存),并且要注意的是,"垃圾回收器"只對這塊區(qū)域起作用;

然而,有些情況下,當(dāng)需要釋放非托管資源時(shí),就必須通過寫代碼的方式來解決。通常是使用析構(gòu)函數(shù)釋放非托管資源,將用戶自己編寫的釋放非托管資源的代碼段放在析構(gòu)函數(shù)中即可。需要注意的是,如果一個(gè)類中沒有使用到非托管資源,那么一定不要定義析構(gòu)函數(shù),這是因?yàn)閷ο髨?zhí)行了析構(gòu)函數(shù),那么"垃圾回收器"在釋放托管資源之前要先調(diào)用析構(gòu)函數(shù),然后第二次才真正釋放托管資源,這樣一來,兩次刪除動(dòng)作的花銷比一次大多的。下面使用一段代碼來示析構(gòu)函數(shù)是如何使用的:

  1. public class ResourceHolder   
  2. {  
  3. …  
  4. ~ResourceHolder()  
  5. {  
  6. // 這里是清理非托管資源的用戶代碼段  
  7. }  
  8. }  

四.C#析構(gòu)函數(shù)小結(jié)

構(gòu)造函數(shù)與C#析構(gòu)函數(shù)雖然是一個(gè)類中形式上較簡單的函數(shù),但它們的使用決非看上去那么簡單,因此靈活而正確的使用構(gòu)造函數(shù)與析構(gòu)函數(shù)能夠幫你更好的理解CLR的內(nèi)存管理機(jī)制,以及更好的管理系統(tǒng)中的資源。

【編輯推薦】

  1. 在Visual Studio 2010中使用C# 4.0的動(dòng)態(tài)類型
  2. C#3.0中Lambda表達(dá)式詳解
  3. 淺談C#泛型的用處
  4. 淺談C#如何實(shí)現(xiàn)多繼承
  5. C#實(shí)用基礎(chǔ)教程
責(zé)任編輯:彭凡 來源: 7880.com
相關(guān)推薦

2009-08-14 17:24:28

C#構(gòu)造函數(shù)和析構(gòu)函數(shù)

2009-09-03 13:14:55

C#構(gòu)造函數(shù)C#析構(gòu)函數(shù)

2009-08-13 14:36:40

C#結(jié)構(gòu)體構(gòu)造函數(shù)

2009-07-31 14:15:38

C# 構(gòu)造函數(shù)

2009-08-24 18:09:13

C#構(gòu)造函數(shù)

2009-07-31 16:06:50

成員函數(shù)構(gòu)造函數(shù)C#

2009-07-31 15:44:02

C#靜態(tài)構(gòu)造函數(shù)

2009-08-14 09:15:28

C#調(diào)用構(gòu)造函數(shù)

2009-09-04 11:15:07

選擇C#構(gòu)造函數(shù)

2009-08-20 14:28:00

C#靜態(tài)構(gòu)造函數(shù)

2009-07-31 15:37:45

C#靜態(tài)構(gòu)造函數(shù)

2009-08-13 17:38:42

C#構(gòu)造函數(shù)

2010-07-20 09:52:27

Perl構(gòu)造函數(shù)

2009-09-02 10:49:46

C#調(diào)用析構(gòu)方法

2009-09-18 09:02:45

CLR Via C#

2009-08-13 18:02:11

C#靜態(tài)構(gòu)造函數(shù)

2009-08-13 18:15:06

C#繼承構(gòu)造函數(shù)

2009-08-14 09:58:09

C#復(fù)制構(gòu)造函數(shù)

2009-08-13 14:24:44

C#結(jié)構(gòu)體構(gòu)造函數(shù)

2009-08-14 09:43:59

C#復(fù)制構(gòu)造函數(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 一区二区三区不卡视频 | 欧美不卡一区 | 精品国产乱码久久久久久蜜柚 | 色欧美片视频在线观看 | 国产成人精品一区二区在线 | 精品免费 | 久久久成人网 | 一区二区三区四区电影 | 一级做a爰片性色毛片视频停止 | 久久久影院 | 祝你幸福电影在线观看 | 欧美国产日韩一区二区三区 | 免费一级片 | 日韩一二三区视频 | 日韩精品一区二区三区在线播放 | 国产精品免费视频一区 | 夜夜爽99久久国产综合精品女不卡 | 琪琪午夜伦伦电影福利片 | 午夜激情影院 | 亚洲高清中文字幕 | 在线视频 欧美日韩 | 日本免费一区二区三区四区 | 久久久精品 | 毛片一区二区三区 | 一级一级毛片免费看 | 成人日b视频 | 日韩精品 电影一区 亚洲 | 国产精品久久久亚洲 | 欧美精品一区二区三区四区五区 | 欧美在线观看一区 | 欧美激情综合五月色丁香小说 | 日日噜噜夜夜爽爽狠狠 | 在线观看成人精品 | 黄网站在线播放 | 成年人在线电影 | 欧美.com | 日本不卡一二三 | 免费a网站| 视频在线亚洲 | 日韩免费在线视频 | 中文字字幕一区二区三区四区五区 |