带引用计数智能指针
2016-01-21 12:44
357 查看
参考:shared_ptr实现,auto_ptr-实现
注1:std::shared_ptr带引用计数
注2:std::auto_ptr不带引用计数(但支持release方法,断开指向)
参考:http://blog.csdn.net/lollipop_jin/article/details/8499530
(Owed by: 春夜喜雨http://blog.csdn.net/chunyexiyu)
std::shared_ptr
<CDemo> ipDemo = new CDemo;
通常提供
.get() method获取裸指针
operator ->同CDemo->使用效果一致
智能指针使用的过程中,不需要对ipDemo进行手动的释放,如果非要手动释放,也不能采用通常的方式
delete ipDeom.get() (错误) ---会引发重复释放的崩溃,原因是手动释放掉了,智能指针也会释放一次。
可以使用
ipDemo = nullptr;
ipDeom.reset(nullptr)来进行手动释放,或者是什么都不做,等待智能指针自动释放
存储引用计数
同时共享引用计数内存地址
(注意shared_ptr是用引用计数的,auto_ptr是无引用计数的)
实现这个有两种方法:
一种引用计数放入到智能指针类中,通过new实现,智能指针存储new出的地址
一种引用计数放入到类中
第一种:
智能指针需要实现:(参考如下代码)
引用计数,在合适的时机删除指针 (申请内存,从而进行计数共享)
Copy构造
(定义时:= new时,或是等于另一个时)
operator = (定义后,再赋值情况)
operator -> (使用->时的情况处理)
.get()方法 (返回裸指针)
当前自己写的一个指针指针的实现参考下面的代码段。
第二种:
需要类里面提供计数,指针类调用类里的计数
支持智能指针的类需要实现
计数变量
提供addRef/ReleaseRef/QueryRef方法
智能指针实现
构造、析构调用类的addRef/ReleaseRef/QueryRef,在合适的时机删除指针
Copy构造
operator =
operator ->
.get()
第一种的样例实现
第二种显现,类中存储引用计数,智能指针只能支持实现计数的类
第一种实现,不支持:(无论是使用auto_ptr还是shared_ptr,都永远不要写这样的代码)
会导致重复释放。
第二种实现,支持上面那种,因为计数存储在类中,上面的代码,会让计数=2,不会产生重复释放的问题。
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
参考:shared_ptr实现,auto_ptr-实现
注1:std::shared_ptr带引用计数
注2:std::auto_ptr不带引用计数(但支持release方法,断开指向)
参考:http://blog.csdn.net/lollipop_jin/article/details/8499530
(Owed by: 春夜喜雨http://blog.csdn.net/chunyexiyu)
1. 什么是智能指针
智能指针通常使用如下std::shared_ptr
<CDemo> ipDemo = new CDemo;
通常提供
.get() method获取裸指针
operator ->同CDemo->使用效果一致
智能指针使用的过程中,不需要对ipDemo进行手动的释放,如果非要手动释放,也不能采用通常的方式
delete ipDeom.get() (错误) ---会引发重复释放的崩溃,原因是手动释放掉了,智能指针也会释放一次。
可以使用
ipDemo = nullptr;
ipDeom.reset(nullptr)来进行手动释放,或者是什么都不做,等待智能指针自动释放
2. 智能指针实现(带引用计数)
智能指针实现的原理是存储引用计数
同时共享引用计数内存地址
(注意shared_ptr是用引用计数的,auto_ptr是无引用计数的)
实现这个有两种方法:
一种引用计数放入到智能指针类中,通过new实现,智能指针存储new出的地址
一种引用计数放入到类中
第一种:
智能指针需要实现:(参考如下代码)
引用计数,在合适的时机删除指针 (申请内存,从而进行计数共享)
Copy构造
(定义时:= new时,或是等于另一个时)
operator = (定义后,再赋值情况)
operator -> (使用->时的情况处理)
.get()方法 (返回裸指针)
当前自己写的一个指针指针的实现参考下面的代码段。
第二种:
需要类里面提供计数,指针类调用类里的计数
支持智能指针的类需要实现
计数变量
提供addRef/ReleaseRef/QueryRef方法
智能指针实现
构造、析构调用类的addRef/ReleaseRef/QueryRef,在合适的时机删除指针
Copy构造
operator =
operator ->
.get()
第一种的样例实现
#pragmaonce template <classT> classCMySharedPtr { public: //构造时置为空 CMySharedPtr() :m_pRefCount(nullptr),m_pPointer(nullptr) {} //析构时,检查计数,释放内存 ~CMySharedPtr() { //释放原有 freeCurrentPointer(); } CMySharedPtr(T*pValue) { //构造 createNewPointer(pValue); } CMySharedPtr(CMySharedPtr&ipValue) { // Copy构造 CopyAutPtr(ipValue); } public: T*get() { returnm_pPointer; } voidoperator =(T*pValue) { if (pValue == nullptr) { //置空-释放原有 freeCurrentPointer(); } else { //释放原有 freeCurrentPointer(); //申请新的 createNewPointer(pValue); } } voidoperator = (CMySharedPtr&ipValue) { //引用计数地址相同:意味着指向同一地址 if (ipValue.m_pRefCount == m_pRefCount) { return; } //释放原有 freeCurrentPointer(); //申请新的 CopyAutPtr(ipValue); } //重载->符号 T*operator ->() { return (get()); } protected: //通过一个指针构造另一个 voidCopyAutPtr(CMySharedPtr&ipValue) { //计数加一 m_pRefCount =ipValue.m_pRefCount; //指针有效时加一 if (m_pRefCount != nullptr) (*m_pRefCount)++; //指针指向 m_pPointer =ipValue.m_pPointer; } //申请新指针 template <classT> voidcreateNewPointer(T*pValue) { m_pRefCount =newint(); *m_pRefCount = 1; m_pPointer =pValue; } //释放原有指针 voidfreeCurrentPointer() { //存在时进行释放 if (m_pPointer != nullptr &&m_pRefCount !=nullptr) { if (*m_pRefCount > 1) { (*m_pRefCount)--; } elseif (*m_pRefCount == 1) { *m_pRefCount = 0; deletem_pPointer; deletem_pRefCount; } } //置初值 m_pPointer =nullptr; m_pRefCount =nullptr; } private: int*m_pRefCount; T*m_pPointer; }; |
3. 智能指针的使用
智能指针使用时,直接使用即可,不用关心它的释放。 classDemo { public: Demo() { printf(("Demo Create\n")); } ~Demo() { printf(("Demo Delete\n")); } public: voidShow() { printf(("Call Demo Show\n")); } }; voidTestCode() { CMySharedPtr<Demo>ipValue =newDemo(); //构造 ipValue->Show(); // 调用operator-> CMySharedPtr<Demo>ipValue2 =ipValue; // copy构造 ipValue2 =ipValue; // 调用operator = ipValue->Show(); } |
4. 两种实现的区别
第一种实现,智能指针中存储引用计数,能支持所有的类型第二种显现,类中存储引用计数,智能指针只能支持实现计数的类
第一种实现,不支持:(无论是使用auto_ptr还是shared_ptr,都永远不要写这样的代码)
Deom* pa = new A; CMySharedPtr<Deom> ptr_a_1(pa); CMySharedPtr<Deom> ptr_a_2(pa); |
会导致重复释放。
第二种实现,支持上面那种,因为计数存储在类中,上面的代码,会让计数=2,不会产生重复释放的问题。
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
相关文章推荐
- MongoDB 参数配置
- NNCRF之NNSegmentation, NNPostagging, NNNameEntity
- 动态加载JS和CSS
- JAVA的null说明
- 下一轮WiFi革命来临:详解高通MU-MIMO技术(Multi-User Multiple-Input Multiple-Output多用户多入多出技术)
- Java网络编程--简易下载器实现
- Java类的实例化过程
- JSON和XML:不可同日而语
- CocoaPods安装和使用教程
- HDOJ 2141 Can you find it?
- 冒泡排序
- 升级python之后,yum下载东西时出现File "/usr/bin/yum", line 30
- 唯品会峰值系统架构演变
- TencentApiInterfaceDelegate 是这个找不到的原因
- C# word 操作页脚书签
- 依据前序和中序列 重建二叉树
- linux-0.12/boot/setup.S`
- 珠排序Bead Sort
- 安卓加载外部数据库
- Special data type: bit, sql_variant