1、shared_ptr<T>解决什么问题?

  auto_ptr有个局限,拥有权转移。这往往不符合我们的需求,有时候我们期望,多个资源管理对象可以共享一个资源,当引用计数为0的时候,执行delete。shared_ptr就是为了解决这个问题。

2、shared_ptr怎么解决这个问题?和auto_ptr类似,除此之外,还有几点需要注意:

3、增加一个字段为引用计数,当引用计数为0的时候,执行delete。引用计数字段不能放在资源管理类中,为什么?

  假设放到资源管理类中,每个资源管理对象都有一个refCount字段,共享一个资源的资源管理对象的refCount取值一样,但是怎么保持一致呢?因为这些对象之间没有关联。同时注意:这里不能把refCount字段声明为static,因为static意味着资源管理类的所有对象共享refCount,而当前的要求是一部分对象共享一个refCount,另一部分对象共享另一个refCount。因此,引用计数要和资源绑定在一起。也就是说,这里需要两层封装:第一层是u_ptr<T>类,对资源封装,增加refCount字段,负责delete。第二层是shared_ptr<T>,对u_ptr<T>封装,判断u_ptr对象的引用计数为0,执行u_ptr的析构方法,间接释放资源。

4、有些情况下,当引用计数为0 的时候,我们不想执行delete,而是其他操作,因此,还需要一个删除器,和引用计数同样的道理,删除器应该放在u_ptr中,这个删除器就是指向方法的指针。

5、auto_ptr的copy构造和copy赋值,要转移拥有权。而shared_ptr的copy构造,引用计数加1,copy赋值对原对象的引用计数减1,引用计数为0,执行delete,同时对rhs的引用计数加1。

6、析构的时候,引用计数减1,引用计数为0,才执行delete。

7、示例代码如下(不完整,只有一部分):

 template <typename T>
class u_ptr
{
template <typename T> friend class shared_ptr;
private:
u_ptr(T* ptr):_ptr(ptr),refCount()
{
} ~u_ptr()
{
delete _ptr;
} T* _ptr;
int refCount;
}; template <typename T>
class shared_ptr
{
public:
shared_ptr(T* ptr):_u_ptr_ptr(new u_ptr<T>(ptr))
{
} shared_ptr(shared_ptr<T>& rhs)
{
_u_ptr_ptr= rhs._u_ptr_ptr;
++_u_ptr_ptr->refCount;
} shared_ptr& operator=(shared_ptr<T>& rhs)
{
if(this!=&rhs)
{
if(--_u_ptr_ptr->refCount ==)
{
delete _u_ptr_ptr;
}
_u_ptr_ptr= rhs._u_ptr_ptr;
++_u_ptr_ptr->refCount;
}
return *this;
} ~shared_ptr()
{
if(--_u_ptr_ptr->refCount ==)
{
delete _u_ptr_ptr;
}
} private:
u_ptr<T>* _u_ptr_ptr;
};

理解shared_ptr<T>的更多相关文章

  1. 理解shared_ptr<T> ---2

    1.引用计数字段不能放在资源管理类中.我们的解决办法是,把引用计数和资源绑在一起,进行二次封装.但是这样存在一个大问题,不同类型的资源管理类不能兼容.也就是说,shared_ptr<Dog> ...

  2. 理解 shared_ptr实现copy-on-write(COW)

    看muduo库某个生产者消费者的地方,利用shared_ptr有效减少了锁的范围及无用的拷贝,下面来看一看 // reader 消费者, shared_ptr<map<string,int ...

  3. 如何用enable_shared_from_this 来得到指向自身的shared_ptr 及对enable_shared_from_this 的理解

    在看<Linux多线程服务端编程:使用muduo C++网络库> 的时候,在说到如何防止在将对象的 this 指针作为返回值返回给了调用者时可能会造成的 core dump.需使用 ena ...

  4. ndk学习之c++语言基础复习----C++线程与智能指针

    线程 线程,有时被称为轻量进程,是程序执行的最小单元. C++11线程: 我们知道平常谈C++线程相关的东东基本都是基于之后要学习的posix相关的,其实在C++11有自己新式创建线程的方法,所以先来 ...

  5. C/C++陷阱与套路,当年就是折在这些地儿…

    摘要:本文结合作者的工作经验和学习心得,对C++语言的一些高级特性,做了简单介绍:对一些常见的误解,做了解释澄清:对比较容易犯错的地方,做了归纳总结:希望借此能增进大家对C++语言了解,减少编程出错, ...

  6. C++智能指针的enable_shared_from_this和shared_from_this机制

    前言 之前学习muduo网络库的时候,看到作者陈硕用到了enable_shared_from_this和shared_from_this,一直对此概念是一个模糊的认识,隐约记着这个机制是在计数器智能指 ...

  7. 深入理解智能指针之shared_ptr(一)

    本文基于C++标准库源码分析shared_ptr,旨在搞清楚shared_ptr是什么,线程安全性等,目标能够安全的使用智能指针. (一)shared_ptr是一个类. 首先可以确定的是shared_ ...

  8. 【STL学习】智能指针之shared_ptr

    前面已经学习过auto_ptr,这里补充另外一种智能指针,比auto_ptr要更强力更通用的shared_ptr. shared_ptr 简介及使用选择  几乎所有的程序都需要某种形式的引用计数智能指 ...

  9. Boost源代码学习---shared_ptr.hpp

    最近观看Boost库源代码.Boost功能强大的库,但它的许多源代码,十一细读太费时间,毕竟,还有其他东西要学.所以我决定脱脂感兴趣的章节,他们的设计思路和难以理解的地方记录. shared_ptr是 ...

随机推荐

  1. javascript里的post和get有什么区别

    FORM中的get post方法区别Form中的get和post方法,在数据传输过程中分别对应了HTTP协议中的GET和POST方法.二者主要区别如下: 1.Get是用来从服务器上获得数据,而Post ...

  2. (2015年郑州轻工业学院ACM校赛题) J 堆

    判断是否是一个堆,把树构造好遍历一遍就OK了 #include<stdio.h> #include<iostream> #include<stack> #inclu ...

  3. SharePoint默认的欢迎WebPart中超链接样式

    转:http://www.cnblogs.com/Bear-Study-Hard/archive/2010/03/22/1691641.html 在core.css文件中 .ms-SpLinkButt ...

  4. SQL Server 2008 R2主数据服务安装

    SQL Server 2008 R2的主数据服务(Master Data Services,简称MDS)已经放出,目前是CTP版本,微软提供了下载地址: http://www.microsoft.co ...

  5. myeclipse2015不能启动tomcat,提示: Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at local

    myeclipse2015不能启动tomcat,提示: Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at local ...

  6. Java was started but returned exit code=13 C:\ProgramData\Oracle\Java\javapath\javaw.exe

    ---------------------------Eclipse---------------------------Java was started but returned exit code ...

  7. 【Python】使用python的tornado配合html页面示例

    背景:java写的非标加密算法,测试时执行java工程进行解密测试,很不方便. 目的:想写个web页面,使得任何测试人员都可以在输入加密串时得到解密后字段,方便日志查询及字段核对.(额,算法部分就不写 ...

  8. HDU4578 Transformation 线段树

    这个题让我重新学习了加 乘 在区间的操作 题解:http://blog.csdn.net/guognib/article/details/25324025?utm_source=tuicool& ...

  9. opencv 在工业中的应用:圆孔定位

    在工业中产品或者夹具上经常有圆形孔,我们可以利用这些孔来对产品或者夹具进行定位.我用OPENCV写了个DEMO 程序,介绍如下: (1)首先点击打开图像按钮打开一幅图像 (2)进行一些参数设置 (3) ...

  10. LeetCode题解——ZigZag Conversion

    题目: 把一个字符串按照Z型排列后打印出来,例如 "PAYPALISHIRING" 重新排列后为3行,即 P A H N A P L S I I G Y I R 那么输出为&quo ...