[5] 智能指針boost::shared_ptr

【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.

順序  選擇  循環  總結

相關文章
相關標籤/搜索