C 中的析構函式

2022-08-28 08:51:10 字數 2412 閱讀 8713

析構函式 

析構函式(destructor) 與建構函式相反,當物件脫離其作用域時(例如物件所在的函式已呼叫完畢),系統自動執行析構函式。析構函式往往用來做「清理善後」 的工作(例如在建立物件時用new開闢了一片記憶體空間,應在退出前在析構函式中用delete釋放)。

以c++語言為例,析構函式名也應與類名相同,只是在函式名前面加乙個波浪符~,例如~stud( ),以區別於建構函式。它不能帶任何引數,也沒有返回值(包括void型別)。只能有乙個析構函式,不能過載。如果使用者沒有編寫析構函式,編譯系統會自動生成乙個預設的析構函式,它也不進行任何操作。所以許多簡單的類中沒有用顯式的析構函式。

解構器我們知道,『解構器』被用來清除類的事例。當我們在c#中使用解構器是,我們必須記住以下幾點:

乙個類只能有乙個解構器。 

解構器不能被繼承或過載。 

解構器不能被呼叫。他們是自動被(編譯器)呼叫的。 

解構器不能帶修飾或引數。 

下面是類myclass解構器的乙個宣告:

~ class()   

程式設計師不能控制解構器何時將被執行因為這是由垃圾收集器決定的。垃圾收集器檢查不在被應用程式使用的物件。它認為這些條件是符合清楚的並且收回它們的記憶體。解構器也在程式退出時被呼叫。當解構器執行時其背後所發生的那一幕是解構器隱式呼叫物件基類的object.finalize方法。因此上述解構器**被隱含轉化成:

protected override void finalize()  

finally  

}creating a

creating b

creating c

object created 

press enter to destroy it

destroying c

destroying b

destroying a

所以,如果一旦你使用完物件你就想呼叫解構器,你該怎麼做?有兩個方法:

呼叫垃圾蒐集器來清理。

實現idisposable的dispose方法。

呼叫垃圾蒐集器

你能通過呼叫gc.collect方法強制垃圾蒐集器來清理記憶體,但在大多數情況下,這應該避免因為它會導致效能問題。在上面的程式中,在gc.collect()處移除注釋。編譯並執行它。現在,你能看到解構器在控制台中被執行了。

實現idisposable介面

idisposable 介面包括僅有的乙個公共方法,其宣告為void dispose()。我們能實現這個方法來關閉或釋放非託管資源如實現了這個介面的類事例所控制的檔案,流,和控制代碼等。這個方法被用做所有任務聯合物件的資源釋放。當實現了這個方法,物件必須尋求確保所有擁有的資源被繼承結構中關聯的資源也釋放(不能把握,翻不出來)。

class myclass:idisposable    }

當我們實現了idisposable介面時,我們需要規則來確保dispose被適當地呼叫。

聯合使用解構器和idisposable介面

public class myclass:idisposable  

protected void dispose(bool diposing)  

//clean up unmanaged resources  

}  isdisposed=true;  

}  ~myclass()    }

在這裡過載了dispose(bool)來做清理工作,並且所有的清理**都僅寫在這個方法中。這個方法被解構器和idisposable.dispose()兩著呼叫。我們應該注意dispose(bool)沒有在任何地方被呼叫除了在idisposable.dispose()和解構器中。

當乙個客戶呼叫idisposable.dispose()時,客戶特意地想要清理託管的和非託管資源,並且因此完成清理工作。有一件你必須注意的事情是我們在清理資源之後立即呼叫了gc.supressfinalize(this)。這個方法通知垃圾蒐集器不需要呼叫解構器,因為我們已經做了清理。

注意上面的例子,解構器使用引數false呼叫dispose。這裡,我們確信垃圾蒐集器蒐集了託管資源。我們僅僅做非託管資源的清理。

結論儘管如此我們花費一些時間實現idisposable介面,如果客戶不能合適地呼叫它們會怎樣?為此c#有乙個酷的解決方案。『using』**塊。它看起來像這樣:

using (myclass objcls =new myclass())  

當控制從using塊通過成功執行到結束或者丟擲異常退出時,myclass的idispose.dispose()將會被執行。記住你例示的物件必須實現system.idisposable介面。using語句定義了哪個物件將被清除的乙個範圍。

注:建構函式與析構函式的區別:

建構函式和析構函式是在類體中說明的兩種特殊的成員函式。

建構函式的功能是在建立物件時,使用給定的值來將物件初始化。

析構函式的功能是用來釋放乙個物件的。在物件刪除前,用它來做一些清理工作,它與建構函式的功能正好相反。

C 中的析構函式

概念 析構函式執行與建構函式相反的操作 建構函式初始化物件的非static的資料成員,析構函式則是釋放物件所用的資源,並銷毀物件的非static資料成員。特徵 析構函式的名字是由波浪線接類名構成,他沒有返回值,也不接受引數,所以析構函式不能被過載。注意 析構函式和建構函式相同,建構函式有乙個函式體和...

C 中的析構函式

在企業應用開發世界,效能,靈活性和安全性是最重要的。我作為乙個vc 程式設計師開始我的職業生涯,並且在乙個晴朗的早晨,我被轉到了web開發部。像每個c 程式設計師一樣,我也很失落。我想每個像tom,dick甚至harry能用html程式設計。然而,不久我就發現真正的挑戰是生產高效能的,靈活的可靠的應...

C 析構函式 虛析構函式

1.為什麼要定義虛析構函式?如果有乙個帶有虛函式功能的類,則它需要乙個虛析構函式,原因如下 1 如果乙個類有虛函式功能,它經常作為乙個基類使用 2 如果它是乙個基類,它的派生類經常使用new來分配 3 如果乙個派生類物件使用new來分配,並且通過乙個指向它的基類的指標來控制,那麼它經常通過乙個指向它...