理解shared_ptr<T>
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>的更多相关文章
- 理解shared_ptr<T> ---2
1.引用计数字段不能放在资源管理类中.我们的解决办法是,把引用计数和资源绑在一起,进行二次封装.但是这样存在一个大问题,不同类型的资源管理类不能兼容.也就是说,shared_ptr<Dog> ...
- 理解 shared_ptr实现copy-on-write(COW)
看muduo库某个生产者消费者的地方,利用shared_ptr有效减少了锁的范围及无用的拷贝,下面来看一看 // reader 消费者, shared_ptr<map<string,int ...
- 如何用enable_shared_from_this 来得到指向自身的shared_ptr 及对enable_shared_from_this 的理解
在看<Linux多线程服务端编程:使用muduo C++网络库> 的时候,在说到如何防止在将对象的 this 指针作为返回值返回给了调用者时可能会造成的 core dump.需使用 ena ...
- ndk学习之c++语言基础复习----C++线程与智能指针
线程 线程,有时被称为轻量进程,是程序执行的最小单元. C++11线程: 我们知道平常谈C++线程相关的东东基本都是基于之后要学习的posix相关的,其实在C++11有自己新式创建线程的方法,所以先来 ...
- C/C++陷阱与套路,当年就是折在这些地儿…
摘要:本文结合作者的工作经验和学习心得,对C++语言的一些高级特性,做了简单介绍:对一些常见的误解,做了解释澄清:对比较容易犯错的地方,做了归纳总结:希望借此能增进大家对C++语言了解,减少编程出错, ...
- C++智能指针的enable_shared_from_this和shared_from_this机制
前言 之前学习muduo网络库的时候,看到作者陈硕用到了enable_shared_from_this和shared_from_this,一直对此概念是一个模糊的认识,隐约记着这个机制是在计数器智能指 ...
- 深入理解智能指针之shared_ptr(一)
本文基于C++标准库源码分析shared_ptr,旨在搞清楚shared_ptr是什么,线程安全性等,目标能够安全的使用智能指针. (一)shared_ptr是一个类. 首先可以确定的是shared_ ...
- 【STL学习】智能指针之shared_ptr
前面已经学习过auto_ptr,这里补充另外一种智能指针,比auto_ptr要更强力更通用的shared_ptr. shared_ptr 简介及使用选择 几乎所有的程序都需要某种形式的引用计数智能指 ...
- Boost源代码学习---shared_ptr.hpp
最近观看Boost库源代码.Boost功能强大的库,但它的许多源代码,十一细读太费时间,毕竟,还有其他东西要学.所以我决定脱脂感兴趣的章节,他们的设计思路和难以理解的地方记录. shared_ptr是 ...
随机推荐
- XSLT 处理程序是如何工作的
与 JSP.PHP 和其他 Web 开发语言的比较 在本文中,Benoit Marchal 考察了 XSLT 处理程序的工作原理.为了说明他的观点,他编写了专门的样式表把处理中的某些方面凸显出来.他特 ...
- Oracle数据库生成UUID
从Data Ghost的blog得知,原来可以用Oracle来生成UUID,做法很简单,如下: select sys_guid() from dual; 数据类型是 raw(16) 有32个字符.
- bzoj2431:[HAOI2009]逆序对数列
单组数据比51nod的那道题还弱...而且连优化都不用了.. #include<cstdio> #include<cstring> #include<cctype> ...
- html的视频插件 (转)
1)jMedia Element是一个基于jQuery/jQuery UI实现的HTML5音频/视频开发工具包.提供非常多的功能来控制页面中的音频和视频内容.当旧的浏览器不兼容HTML5时, ...
- 浅析WCF与WebService、WPF与Silverlight 区别
由于在<Windows服务调用Quartz.net 实现消息调度>中,涉及到ASP.NET Web Service //WebServiceSoapClient client = new ...
- MFC 状态栏相关使用(CStatusBar & CStatusBarCtrl)
原文:MFC 状态栏相关使用(CStatusBar & CStatusBarCtrl),沙漠紫风铃 本文介绍了MFC中和状态栏相关的用法: 在MFC的的单文档应用中,在建好应用程序之后,CMa ...
- java jvm学习笔记六(实现写自己的安全管理器)
安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用AccessController的checkPerssiom方法,访问控 ...
- BNU 51275 道路修建 Large 并查集
分析(引入Q神题解 %%%Q) 如果使用可持久化并查集,二分答案判定连通性,复杂度是O(mlog3n),不能在时限内出解.考虑到并查集实际上是一棵树,可以尝试在边上维护一些信息,假设t时刻加了一条边 ...
- hive内部表与外部表区别
1.在Hive里面创建一个表: hive> create table wyp(id int, > name string, > age int, > tele ...
- Cppcheck代码分析(2)
功能 解析函数中的可能的代码执行流 函数实际执行中只会执行代码流中的一条流 分析: 分支语句 if-else ,switch-case 循环语句 while, do-while ,for 代码流举例 ...