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

顺序  选择  循环  总结

相关文章
相关标签/搜索