shared_ptr是新的標準庫的一個主要成員,作為一個非嵌入式的智能指針,其設計可謂已經是絞盡腦汁。當然,還有很多人對它提出了不滿。沒有完美的設計,只有合適的設計。
1. shared_ptr最大的特點是接口的簡單性與實現的靈活性。
對于shared_ptr<Object>,object的內存管理是可定制的,甚至可以定制引用計數結點的內存分配,以滿足對內存有特殊要求的情況。而這一切,都被Object的實現者隱藏起來,使用Object的客戶類是不用關心的。這和以前標準庫的組件實現策略有些不同。比如說, vector<int, A1>和vector<int, A2>,由于內存分配策略的不同,而變成類型的不同,造成接口的改變。這一點在shared_ptr的設計時被避免了,當然以一定的性能代價。shared_ptr作為C++面向對象設計的一個重要組件,接口的簡單性是很重要的,必須要有接口和實現的分離。與此相似的還有tr1::function的設計。
2.在同一體系中,各種類型的智能指針可以互相轉換。
如下例:
struct Object : InterfaceA, InterfaceB {
MemberA memberA;
};
shared_ptr<Object> obj(new Object);
shared_ptr<InterfaceA> a = obj;
shared_ptr<InterfaceB> b = obj;
shared_ptr<Object> p = static_pointer_cast<Object>(b);
shared_ptr<void> p2 = obj;
甚至還可以取得數據成員的智能指針:
shared_ptr<Object> obj(new Object);
shared_ptr<MemberA> memberA(obj, &obj->memberA);
再來說說shared_ptr的缺點。
1.對于使用引用計數的智能指針來說,必須要小心出現循環引用。
在重度使用shared_ptr的系統中,你必須一開始就明確類與類的關系,以決定哪里使用shared_ptr,哪里使用weak_ptr,否則就會出現內存泄露。而
shared_ptr的接口轉換的靈活性,也很容易導致智能指針被濫用。內存自動管理的問題并沒有得到解決,它只是被轉移了。
2.shared_ptr使用非嵌入式設計,這樣可以使用于基本類型,比如 shared_ptr<int>。但是根據個人經驗,這種情況在很少使用。大部分情況還是使用自己設計的類。這有一個問題,就是沒有很方便的辦法實現this指針和智能指針的轉換。標準庫中提供了enable_shared_from_this類來解決這個問題。但這已經使所謂的
非嵌入式設計徒有虛名。而假如一開始采用
嵌入式設計的話,則在性能代價和多線程設計方面具有更大的靈活性。