前言
自從1993年Microsoft首次公布了COM技術以後,Windows平台上的開發模式發生了巨大的變化,以COM為基礎的一系列軟件組件化技術將Windows編程帶入了組件化時代。直至如今,COM技術仍然煥發著旺盛的生命力,大量組件和軟件都通過COM技術實現了復用和資源共享。
由於技術復雜,COM編程一度被視為一種高不可攀的技術,令人望而卻步。COM將Windows推向組件化時代的同時,也將開發和使用COM組件的程序員推上了另外一座危險的山峰。那裡高不可攀,四處潛藏著陷阱與玄機,稍有不慎便會摔得粉身碎骨。
現在,設想你已經站到了COM為你隆起的山峰上。四面是懸崖峭壁,若是一步不小心,就將滑落到谷底深淵,命懸一線。我若是此時給你一頂降落傘背在身後,我想你肯定不會拒絕。
而COM接口的智能指針,正是解決COM技術中引用計數問題的一頂“降落傘”。雖然他不能保證你不會摔下懸崖,但總不至於摔死得很難看。
或許很多人拒絕使用COM接口智能指針的原因和拒絕使用“降落傘”是一樣的:
1.你需要學習正確使用它的方法。(如你得知道什麼時候打開你的降落傘);
2.你需要避免它帶來的負面影響,避免它引入的新的風險。(你得知道你拉開降落傘後如何不被掛在樹上,或者不被大風吹打到另一堵懸崖上);
明白了這些以後我想你還是願意選擇使用智能指針來代替原始的手動引用計數。若是你比較執著的認為原始的手動操作引用計數更加能使得代碼清晰明確的話。那麼你可能要遭受來自“異常安全”、“類型安全”等問題的困擾。更為遺憾的是,手動計數,並不會是代碼更加清晰。在本文的第一章你將會看到這些內容。
我曾經聽人說:“不要使用智能指針,因為有時候搞不清他是智能指針還是接口指針。”這種想法確實相當有道理,因為我們希望程序盡可能的清晰易懂。而智能指針會隱藏很多實現細節。對於不熟悉他的人來說,你可能並不知道他在某一時刻所做的某種“智能化”操作。但如果通過本文,你能夠清楚這些實現細節,並有針對性的采取相應的解決辦法。似乎會比直接拒絕使用它有價值得多。
本文主要想討論的問題是智能指針的使用和設計。我們討論智能指針處理某些問題的做法,並盡可能的解析出之所以這樣做的一些歷史的、平台的背景,以及他所遵守的某種設計上的原則。並從中挖掘出可以指導我們將來設計的一些指導思想,我將這些思想以章節和條款的形式組織在一起。
第一章中,你將能夠對COM接口智能指針的使用有個粗略的了解。並從中明白智能指針使用時候需要遵守的一些條款和規則。
第二章中,我們討論,智能指針在使用規則上的若干問題。告訴你如何正確的使用智能指針而不淪落到內存和資源洩漏的困境中。
第三章中,我們討論設計一套智能指針所需要遵循的原則,並且在矛盾發生時如何在這些原則中進行取捨。
第四章中,我們討論具體實現中的細節,他會具體到一個接口應該如何編寫,如何通過一些技巧讓設計出來的接口不易被誤用,以及智能指針編寫過程中的各種細節。
最後一章,是關於一些遺留下來的雜項的討論。這些東西往往是有爭議的,因此有些智能指針的設計者會采用它,而有的則不會。我們以一個中立的態度看待這些問題,並給出鄉音的解決方案。
通過這篇文檔,我盡量挖掘智能指針背後所隱藏的一些問題,從而使得我們可以更加有效的使用和正確的設計出適合自己項目的COM智能指針。為了舉例論證某些觀點,我編寫了大量的示例(部分示例改編自其他論文,我在相應的地方著名了出處)。我對這些示例中產生的問題和原因逐一的剖析,希望讀完之後讀者能有豁然開朗的效果。
由於編者水平有限,本文諸多地方可能還存在著錯誤。還望讀者多多指正。
作者“liuchang5的專欄”