智能指针boost::shared_ptr

转载 2013年12月03日 14:22:52

【1】boost::shared_ptr简介

boost::shared_ptr属于boost库,定义在namespace boost中,包含头文件#include<boost/shared_ptr.hpp>便可以使用。

上篇boost::scoped_ptr中我们看到boost::scoped_ptr独享所有权,不允许赋值、拷贝。

而boost::shared_ptr是专门用于共享所有权的,由于要共享所有权,其在内部使用了引用计数机制。同时也就意味着支持赋值和拷贝。

boost::shared_ptr也是用于管理单个堆内存对象的。

【2】boost::shared_ptr详解

应用实例代码如下:

复制代码
 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()函数。

关键的一点,boost::shared_ptr内部维护了一个引用计数,由此可以支持复制、参数传递等。

boost::shared_ptr提供了一个函数use_count(),此函数返回 boost::shared_ptr内部的引用计数。

查看执行结果,我们可以看到在 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。

关于boost智能指针使用的一些坑的总结

boost库的智能指针确实是一个好东西,可以方便我们进行内存管理,避免因为忘记调用delete而导致的内存泄漏。然而boost库的只能指针却并非一定那么智能,在使用boost库智能指针的时候有一些坑,...
  • tgxallen
  • tgxallen
  • 2017年04月09日 15:30
  • 1687

C++ boost智能指针详解

一、简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执...
  • fengdetianguofeng
  • fengdetianguofeng
  • 2013年12月27日 15:18
  • 427

C++智能指针shared_ptr的三种使用方式

智能指针通常是指基于引用计数的智能指针,在c++11标准中就是std::shared_ptr。它的特点是如果可以安全的放入STL容器中。 有以下三种方式可以使用shared_ptr 1. 如果你的...
  • fanyun_01
  • fanyun_01
  • 2017年03月31日 12:39
  • 1189

boost库在工作(9)引用计数的智能指针shared_ptr之二

接着下来,需要演示一下怎么样在多个对象里共享一个对象,而不管每个对象的生命周期,就可以及时地把使用的对象在合适地方删除。下面的例子里先定义两个类,然后每个类都引用共享的对象,接着使用完成后,就会在析构...
  • superbfly
  • superbfly
  • 2013年07月17日 08:02
  • 959

shared_ptr智能指针模板类的简单实现(c++11)

前言 最近突然萌生把stl常用的库都通通自己过一遍的想法,算是对泛型编程的一次学习,也深入理解stl,还是对c++11知识的练习,就从智能指针开始吧。 另外,c++11让c++程序变得简洁优...
  • to_be_better
  • to_be_better
  • 2016年12月11日 04:51
  • 874

从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)

一、boost 智能指针 智能指针是利用RAII(Resource Acquisition Is Initialization:资源获取即初始化)来管理资源。关于RAII的讨论可以参考前面的文 章。在...
  • Simba888888
  • Simba888888
  • 2013年07月29日 17:15
  • 12299

Boost 共享指针 共享数组

共享指针 shared_ptr已经作为技术报告1(TR1)的一部分被添加到标准。如果开发环境允许,可以使用memory中定义的std::shared_ptr。 在Boost C++库里,类...
  • PeterPan_hai
  • PeterPan_hai
  • 2016年06月21日 14:10
  • 1160

utilities(C++)——单例(Singleton) (使用智能指针 shared_ptr)

utilities(C++)——单例(Singleton) 上文简单版的单例类的实现的一大核心问题,在于new出来的堆对象不会被释放,就有可能造成内存泄漏的风险。class Singleton { p...
  • lanchunhui
  • lanchunhui
  • 2016年03月13日 16:16
  • 1955

智能指针原理分析与自己的shared_ptr实现

原理分析内存管理历来是C++编程的一项需要小心费力气的活,因为C++本身不带GC机制,所有的内存管理都需要我们手动实现,从malloc / free 到new / delete,再到allocator...
  • huoyefeiwu
  • huoyefeiwu
  • 2015年05月29日 00:05
  • 2180

boost::shared_ptr的线程安全

官方文档的说明 shared_ptr objects offer the same level ofthread safety as built-in types. A shared_ptr ins...
  • WLFIGHTER
  • WLFIGHTER
  • 2015年12月06日 16:48
  • 1608
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:智能指针boost::shared_ptr
举报原因:
原因补充:

(最多只允许输入30个字)