最近嘗試寫一些基本的C++泛型組件,其實不少都是boost裏已經有了,可是仍是喜歡本身再寫一下, 緣由有三:
1. boost太龐大,拿來學習不錯,可是通常不會直接在項目中把它import進來。
2. C++11也挺不錯,可是如今工做仍是以VS2008爲主,因此這些新特性暫時用不上。
3. 重複造輪子才能更好的理解輪子背後的原理,之後才能更好的操做輪子。
看一些庫時發現僅指針一項就有挺多封裝, 思考爲何須要智能指針?
經過智能指針能夠以RAII的方式管理對象, 編寫異常安全的代碼; 原始的指針沒有標明對象全部權的狀況, 對象是你單獨擁有的?仍是你和別人共享對象, 可是你也參與管理? 仍是你只是使用對象,可是沒有全部權? 智能指針很好的解決了這些問題。
下面是一些常見的智能指針封裝形式:
std::auto_ptr
基於全部權的智能指針,每次賦值或是拷貝構造都是全部權的轉移,因此不能放到標準容器中。
unique_ptr
一樣是基於全部權的智能指針,不支持賦值或是拷貝構造,可是由於C++11 Move語義和右值引用的支持,能夠經過Move的方法放置到容器中。
proxy_ptr
僅是原始指針的封裝代理,和普通指針沒有什麼區別, 不參與對象生命週期的管理。
ref_ptr (intrusive_ptr)
入侵式的引用計數智能指針,對象自己具備引用計數功能, 外部指針經過對象的引用計數管理該對象的生命週期。不少框架和庫都是基於這種方式, 典型COM組件開發中的CComPtr就是這種類型的指針。
shared_ptr
非入侵式的引用計數智能指針,對象自己不須要計數功能,外部指針在建立對象時會本身建立計數功能並與對象綁定。這種方式使用起來很是方便,可是若是使用不當也會有不少問題, 具體參見
shared_ptr四宗罪
weak_ptr
通常配合share_ptr一塊兒使用, 由於weak_ptr自己不參與對象引用計數的管理,可是它能查詢所引用的對象是否還有效, 因此經過weak_ptr能夠解決循環引用的問題。
在寫泛型代碼的過程當中,會有對程序失去控制的感受,好比下面的代碼:
//C++ 11
class bigclass {};
void fun(bigclass& b){}
int main()
{
bigclass c;
std::thread t(&fun, c);
t.join();
return 0;
}
你知道上面的c對象被拷貝了多少次嗎? 若是改爲std::ref(c)後呢?
咱們用C寫代碼時能夠明確知道每行代碼最終彙編執行時的狀況。
用經典C++(面向對象)寫代碼時, 若是C++基礎紮實,也能夠大概知道背後的彙編代碼, 無非是多些構造,拷貝,賦值,析構,多態等。
可是用現代C++(面向對象+泛型), 你卻很難知道最終展開後的彙編代碼狀況, 由於泛型與對方傳的類型密切相關, 可能你一不當心,對象就被拷貝了N多份,而你還渾然不知。
越抽象的東西離底層機器就越遙遠, C++隔着複雜的編譯器, Java/C#隔着虛擬機, 腳本語言隔着解釋器, 這就是高級語言的代價。
看一些開源的東西,愈來愈以爲博客沒啥好寫了,基礎的東西你們都懂, 高級的東西我也不懂,不知道之前爲何有勇氣寫這麼多東西 ^_^
附上最近模仿的一點東西:
MySLib