【1】boost::shared_ptr簡介html
boost::shared_ptr屬於boost庫,定義在namespace boost中,包含頭文件#include<boost/shared_ptr.hpp>即可以使用。ios
上篇《智能指針boost::scoped_ptr》中咱們看到boost::scoped_ptr獨享全部權,不容許賦值、拷貝。安全
而boost::shared_ptr是專門用於共享全部權的,因爲要共享全部權,其在內部使用了引用計數機制。同時也就意味着支持賦值和拷貝。函數
boost::shared_ptr也是用於管理單個堆內存對象的。spa
【2】boost::shared_ptr詳解指針
應用實例代碼以下:code
1 #include <iostream>
2 #include <boost/shared_ptr.hpp>
3
4 class Int 5 { 6 public: 7 Int(int nValue = 0) 8 { 9 m_nValue = nValue; 10 std::cout << "Constructor: " << m_nValue << std::endl; 11 } 12 ~Int() 13 { 14 std::cout << "Destructor: " << m_nValue << std::endl; 15 } 16 void PrintValue() 17 { 18 std::cout << "PrintValue: " <<m_nValue<< std::endl; 19 } 20 void SetValue(int nSetValue) 21 { 22 m_nValue = nSetValue; 23 } 24
25 private: 26 int m_nValue; 27 }; 28
29 void TestShared_Ptr(boost::shared_ptr<Int> spInt) 30 { // 注意:無需使用 reference (或 const reference)
31 spInt->PrintValue(); 32 std::cout << "TestShared_Ptr UseCount: " << spInt.use_count() << std::endl; 33 } 34
35 void TestShared_Ptr2() 36 { 37 boost::shared_ptr<Int> spInt(new Int(10)); 38 if (spInt.get()) 39 { 40 spInt->PrintValue(); 41 spInt.get()->SetValue(20); 42 spInt->PrintValue(); 43 (*spInt).SetValue(30); 44 spInt->PrintValue(); 45 } 46
47 std::cout << "TestShared_Ptr2 UseCount: " << spInt.use_count() << std::endl; 48 TestShared_Ptr(spInt); 49 std::cout << "TestShared_Ptr2 UseCount: " << spInt.use_count() << std::endl; 50
51 //spInt.release();// 編譯 error: 一樣,shared_ptr也沒有release函數
52 } 53
54 //執行結果以下:
55 /*
56 Constructor: 10 57 PrintValue: 10 58 PrintValue: 20 59 PrintValue: 30 60 TestShared_Ptr2 UseCount: 1 61 PrintValue: 30 62 TestShared_Ptr UseCount: 2 63 TestShared_Ptr2 UseCount: 1 64 Destructor: 30 65 */
實例可見,boost::shared_ptr也能夠很方便的使用。而且沒有release()函數。htm
關鍵的一點,boost::shared_ptr內部維護了一個引用計數,由此能夠支持複製、參數傳遞等。對象
boost::shared_ptr提供了一個函數use_count(),此函數返回 boost::shared_ptr內部的引用計數。blog
查看執行結果,咱們能夠看到在 TestShared_Ptr2函數中,引用計數爲1,傳遞參數後(此處進行了一次複製),
在函數TestShared_Ptr內部,引用計數爲2,在TestShared_Ptr返回後,引用計數又下降爲1。
另外,由TestShared_Ptr2內建立智能指針對象,到函數結束再析構智能指針對象,確保釋放掉內存資源。
當咱們須要使用一個共享對象的時候,boost::shared_ptr是最佳選擇。
此例也正體現了boost::shared_ptr是支持值語義,提供引用計數機制及RAII支持的智能指針。
【3】boost::shared_ptr總結
boost::shared_ptr的管理機制其實並不複雜,就是對所管理的對象進行了引用計數。
當新增一個boost::shared_ptr對該對象進行管理時,就將該對象的引用計數加一;
減小一個boost::shared_ptr對該對象進行管理時,就將該對象的引用計數減一;
若是該對象的引用計數爲0的時候,說明沒有任何指針對其管理,才調用delete釋放其所佔的內存。
boost::shared_ptr並非絕對安全,下面幾條規則能使咱們更加安全的使用boost::shared_ptr:
1.避免對shared_ptr所管理的對象的直接內存管理操做,以避免形成該對象的重釋放
2.shared_ptr並不能對循環引用的對象內存自動管理(這點是其它各類引用計數管理內存方式的通病)。
3.不要構造一個臨時的shared_ptr做爲函數的參數。
以下列代碼則可能致使內存泄漏:
1 void test() 2 { 3 fun(boost::shared_ptr<Int>(new Int()).g()); 4 } 5 //正確的用法爲:
6 void test() 7 { 8 boost::shared_ptr<Int> spInt(new Int()); 9 fun(spInt.g()); 10 }
當函數g()拋異常的時候就會泄露了,這個是boost文檔上特意註明的標準bad Practices。
Good Good Study, Day Day Up.
順序 選擇 循環 總結