要說C++對象是怎麼死的,得先從C++的解構函式說起。這玩意兒是我本人很喜歡的一個語言特性(可惜有好幾個語言沒有類似的玩意兒,具體就不點名
了,免得引發口水戰)。我們可以利用C++的構造和解構函式,來實現Guard模式,寫出比較清晰、簡練和異常安全的代碼。由於Guard模式在C++程式中運用挺多,所以保證所有對象被析構
就是一個很重要很嚴肅的問題。
另外,我發現很多C++程式員只關心記憶體泄露問題,不關心(或不清楚)資源流失問題(很類似於我在“Java新手通病[3]
”提到的現象)。比如昨天的“C++對象是怎麼死的?進程篇
”
發布後,就有同學問了:進程死都死了,對象沒銷毀又有什麼關係捏?其實大有關係啊!雖然作業系統會在進程死後幫它收屍(也就是把某些資源,比如記憶體進行回
收),基本不用擔心記憶體泄露的問題。但是別忘了,除了記憶體資源,進程中可能還包含有其它業務層面的資源,而這些資源,作業系統是不會幫你自動回收的。所以
我要再囉嗦一次:資源流失往往比記憶體泄露要嚴重得多啊
。囉嗦完之後,為了加深印象,再舉如下一個例子。
比如某商務邏輯Foo需要操作大量的臨時檔案(放在某動態產生的臨時目錄中),為了保證該商務邏輯結束後(可能是正常結束,也可能中途拋出異常),該臨時目錄總是被刪除,可以使用如下的Guard模式。
class CTempDirGuard
{
public:
CTempDirGuard(const string& sFolderName)
{
// 建立某臨時目錄
}
virtual ~CTempDirGuard()
{
// 把該臨時目錄整個兒刪除
}
};
void Foo()
{
CTempDirGuard guard(xxx); // 聲明guard對象
// 往臨時目錄放東西
// 不管是出現return語句還是有異常拋出,guard都會被析構,因而該xxx目錄會被刪除
// 但是如果程式執行到此處,卻發生進程的非自然死亡,
// 在這種情況下,該guard對象將不會被析構,因此會留下一個垃圾目錄,浪費了硬碟資源
}
鑒於上述所說的兩個原因,所以我一直想寫一個這方面的文章。正好前幾天寫了文章討論“架構設計的多進程問題
”,之後就就順便寫了一個文章:“C++進程是怎麼死的?”,討論了一下由於進程不同的死法對C++對象析構的影響。等寫完之後突然想到:除了進程終止的問題可能導致C++對象的不
正常析構,還有線程等其它因素也可能會讓C++對象不
正常析構。所以乾脆就改了個名,叫“C++ 對象是怎麼死的?”
另外,為了方便閱讀,把本系列文章的目錄整理如下:
1、進程篇
2、對標準輸入輸出資料流的進一步探討
3、Win32線程篇
4、POSIX線程(pthread)篇
5、......
著作權聲明
本部落格所有的原創文章,作者皆保留著作權。轉載必須包含本聲明,保持本文完整,並以超連結形式註明作者編程隨想
和本文原始地址:
http://program-think.blogspot.com/2009/02/cxx-object-destroy-overview.html