C++智能指针总结
2016-03-24 15:37
501 查看
智能指针RAII:资源分配及初始化,定义一个类来封装资源的分配和初始化,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放
[align=left]#pragmaonce[/align]
[align=left]//AutoPtr 智能指针[/align]
[align=left]template<classT>[/align]
[align=left]classAutoPtr[/align]
[align=left]{[/align]
[align=left]public:[/align]
[align=left] //构造函数[/align]
[align=left] AutoPtr(T*ptr)[/align]
[align=left] :_ptr(ptr)[/align]
[align=left] {}[/align]
[align=left] //拷贝构造[/align]
[align=left] //把ap1股给ap2后,再把自己置为空,不再管理这个内存空间[/align]
[align=left] AutoPtr(AutoPtr<T>&ap)[/align]
[align=left] :_ptr(ap._ptr)[/align]
[align=left] {[/align]
ap._ptr
=NULL;
[align=left] }[/align]
[align=left] //赋值运算符重载[/align]
[align=left] //释放ap3,让ap3指向ap2所指空间,再把ap2置空[/align]
AutoPtr<T>&
operator=(AutoPtr<T>&ap)
[align=left] {[/align]
if(this!=
&ap)
[align=left] {[/align]
cout <<"delete:"<<
_ptr << endl;
[align=left] delete_ptr;[/align]
[align=left]
[/align]
[align=left] _ptr =ap._ptr;[/align]
ap._ptr
=NULL;
[align=left] }[/align]
[align=left]
[/align]
[align=left] return*this;[/align]
[align=left] }[/align]
[align=left] //析勾函数[/align]
[align=left] ~AutoPtr()[/align]
[align=left] {[/align]
[align=left] if(_ptr)[/align]
[align=left] {[/align]
cout <<"delete:"<<
_ptr << endl;
[align=left] delete_ptr;[/align]
[align=left] _ptr =NULL;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] //operator*[/align]
T&
operator*()
[align=left] {[/align]
[align=left] return*_ptr;[/align]
[align=left] }[/align]
[align=left] //operator->[/align]
T*
operator->()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left] //getPtr[/align]
T*
GetPtr()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left]protected:[/align]
T*
_ptr;
[align=left]};[/align]
[align=left]
[/align]
[align=left]// 智能指针管理一块内存的释放[/align]
[align=left]// 智能指针是一个类,有类似指针的功能[/align]
[align=left]structNode[/align]
[align=left]{[/align]
[align=left] int_data;[/align]
Node*
_next;
[align=left]};[/align]
[align=left]
[/align]
[align=left]voidTestAutoPtr()[/align]
[align=left]{[/align]
int*
p1 =newint(2);
int*
p2 = p1;
int*
p3;
[align=left] p3 = p2;[/align]
[align=left]
[/align]
[align=left] *p1 = 10;[/align]
[align=left] //会造成两次析勾,类似于浅拷贝,ap1,ap2都指向同一块内存空间,第一个析勾后,[/align]
[align=left] //第二个就成为野指针[/align]
AutoPtr<int>
ap1(newint(1));
AutoPtr<int>
ap2 = ap1; //AutoPtr ap2(ap1);
[align=left] //释放ap3,让ap3指向ap2所指空间,再把ap2置空[/align]
AutoPtr<int>
ap3(newint(3));
[align=left] ap3 = ap2;[/align]
[align=left] *ap3 = 10;[/align]
[align=left] //*ap1 = 30;[/align]
[align=left]
[/align]
AutoPtr<Node>
apNode(newNode);
[align=left] apNode->_data = 10;[/align]
[align=left]
[/align]
[align=left] deletep1;[/align]
[align=left]}[/align]
[align=left]//AutoPtr容易出错,因为前面的指针已经置为空,存在潜在危险,没有完全达到指针的效果,[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]//ScopedPtr 智能指针[/align]
[align=left]template<classT>[/align]
[align=left]classScopedPtr[/align]
[align=left]{[/align]
[align=left]public:[/align]
[align=left] //构造函数[/align]
[align=left] ScopedPtr(T*ptr)[/align]
[align=left] :_ptr(ptr)[/align]
[align=left] {}[/align]
[align=left] //析勾函数[/align]
[align=left] ~ScopedPtr()[/align]
[align=left] {[/align]
[align=left] if(_ptr)[/align]
[align=left] {[/align]
cout <<"delete:"<<
_ptr << endl;
[align=left] delete_ptr;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] //重载*[/align]
T&
operator*()
[align=left] {[/align]
[align=left] return*_ptr;[/align]
[align=left] }[/align]
[align=left] //operator->[/align]
T*
operator->()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left] //GetPtr[/align]
T*
GetPtr()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left]protected:[/align]
[align=left] //1.限定符为protected,不能进行拷贝,2.将拷贝构造和赋值运算符的重载声明出来[/align]
[align=left] //不能让他调用默认的,也不能在外面定义它[/align]
ScopedPtr(constScopedPtr<T>&
sp);
ScopedPtr<T>
operator=(constScopedPtr<T>&
sp);
[align=left]
[/align]
[align=left]protected:[/align]
T*
_ptr;
[align=left]};[/align]
[align=left]
[/align]
[align=left]//防止别人在类外面定义它[/align]
[align=left]//template<class T>[/align]
[align=left]//ScopedPtr<T>::ScopedPtr(const ScopedPtr<T>& sp)[/align]
[align=left]// :_ptr(sp._ptr)[/align]
[align=left]//{}[/align]
[align=left]
[/align]
[align=left]voidTestScopedPtr()[/align]
[align=left]{[/align]
ScopedPtr<int>
sp1(newint(1));
[align=left] //ScopedPtr<int> sp2(sp1);[/align]
[align=left]}[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]//SharedPtr 利用引用计数来解决这个问题[/align]
[align=left]template<classT>[/align]
[align=left]classSharedPtr[/align]
[align=left]{[/align]
[align=left]public:[/align]
[align=left] SharedPtr(T*ptr)[/align]
[align=left] :_ptr(ptr)[/align]
[align=left] , _pCount(newlong(1))[/align]
[align=left] {}[/align]
[align=left]
[/align]
[align=left] ~SharedPtr()[/align]
[align=left] {[/align]
[align=left] _Release();[/align]
[align=left] }[/align]
[align=left] //只是改变pcount[/align]
[align=left] SharedPtr(constSharedPtr<T>&sp)[/align]
[align=left] :_ptr(sp._ptr)[/align]
[align=left] , _pCount(sp._pCount)[/align]
[align=left] {[/align]
[align=left] ++(*_pCount);[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] ////赋值运算符的传统写法[/align]
//SharedPtr<T>& operator=(const
SharedPtr<T>& sp)
[align=left] //{[/align]
[align=left] // if (this != &sp)[/align]
[align=left] // {[/align]
[align=left] // this->_Release(); [/align]
// _pCount
= sp._pCount;
// _ptr =
sp._ptr;
[align=left] // ++(*_pCount);[/align]
[align=left] // }[/align]
[align=left] // return *this;[/align]
[align=left] //}[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left] //现代写法[/align]
SharedPtr<T>&
operator=(SharedPtr<T>sp)
[align=left] {[/align]
[align=left] swap(_ptr,sp._ptr);[/align]
[align=left] swap(_pCount,sp._pCount);[/align]
[align=left]
[/align]
[align=left] return*this;[/align]
[align=left] }[/align]
[align=left]
[/align]
T&
operator*()
[align=left] {[/align]
[align=left] return*_ptr;[/align]
[align=left] }[/align]
[align=left]
[/align]
T*
operator->()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left]
[/align]
T*
GetPtr()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] longGetCount()[/align]
[align=left] {[/align]
[align=left] return*_pCount;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left]protected:[/align]
[align=left] void_Release()[/align]
[align=left] {[/align]
[align=left] //如果指向这个的引用计数为0才delete,其他时候只是前置减减[/align]
if(--(*_pCount)
== 0)
[align=left] {[/align]
[align=left] delete_ptr;[/align]
[align=left] delete_pCount;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left]protected:[/align]
T*
_ptr;
long*
_pCount;
[align=left]};[/align]
[align=left]
[/align]
[align=left]voidTestSharedPtr()[/align]
[align=left]{[/align]
SharedPtr<int>
sp1(newint(1));
SharedPtr<int>
sp2(sp1);
[align=left] cout << sp1.GetCount() << endl;[/align]
[align=left]
[/align]
SharedPtr<int>
sp3(newint(2));
[align=left] sp3 = sp1;[/align]
[align=left]}[/align]
[align=left]#pragmaonce[/align]
[align=left]//AutoPtr 智能指针[/align]
[align=left]template<classT>[/align]
[align=left]classAutoPtr[/align]
[align=left]{[/align]
[align=left]public:[/align]
[align=left] //构造函数[/align]
[align=left] AutoPtr(T*ptr)[/align]
[align=left] :_ptr(ptr)[/align]
[align=left] {}[/align]
[align=left] //拷贝构造[/align]
[align=left] //把ap1股给ap2后,再把自己置为空,不再管理这个内存空间[/align]
[align=left] AutoPtr(AutoPtr<T>&ap)[/align]
[align=left] :_ptr(ap._ptr)[/align]
[align=left] {[/align]
ap._ptr
=NULL;
[align=left] }[/align]
[align=left] //赋值运算符重载[/align]
[align=left] //释放ap3,让ap3指向ap2所指空间,再把ap2置空[/align]
AutoPtr<T>&
operator=(AutoPtr<T>&ap)
[align=left] {[/align]
if(this!=
&ap)
[align=left] {[/align]
cout <<"delete:"<<
_ptr << endl;
[align=left] delete_ptr;[/align]
[align=left]
[/align]
[align=left] _ptr =ap._ptr;[/align]
ap._ptr
=NULL;
[align=left] }[/align]
[align=left]
[/align]
[align=left] return*this;[/align]
[align=left] }[/align]
[align=left] //析勾函数[/align]
[align=left] ~AutoPtr()[/align]
[align=left] {[/align]
[align=left] if(_ptr)[/align]
[align=left] {[/align]
cout <<"delete:"<<
_ptr << endl;
[align=left] delete_ptr;[/align]
[align=left] _ptr =NULL;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] //operator*[/align]
T&
operator*()
[align=left] {[/align]
[align=left] return*_ptr;[/align]
[align=left] }[/align]
[align=left] //operator->[/align]
T*
operator->()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left] //getPtr[/align]
T*
GetPtr()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left]protected:[/align]
T*
_ptr;
[align=left]};[/align]
[align=left]
[/align]
[align=left]// 智能指针管理一块内存的释放[/align]
[align=left]// 智能指针是一个类,有类似指针的功能[/align]
[align=left]structNode[/align]
[align=left]{[/align]
[align=left] int_data;[/align]
Node*
_next;
[align=left]};[/align]
[align=left]
[/align]
[align=left]voidTestAutoPtr()[/align]
[align=left]{[/align]
int*
p1 =newint(2);
int*
p2 = p1;
int*
p3;
[align=left] p3 = p2;[/align]
[align=left]
[/align]
[align=left] *p1 = 10;[/align]
[align=left] //会造成两次析勾,类似于浅拷贝,ap1,ap2都指向同一块内存空间,第一个析勾后,[/align]
[align=left] //第二个就成为野指针[/align]
AutoPtr<int>
ap1(newint(1));
AutoPtr<int>
ap2 = ap1; //AutoPtr ap2(ap1);
[align=left] //释放ap3,让ap3指向ap2所指空间,再把ap2置空[/align]
AutoPtr<int>
ap3(newint(3));
[align=left] ap3 = ap2;[/align]
[align=left] *ap3 = 10;[/align]
[align=left] //*ap1 = 30;[/align]
[align=left]
[/align]
AutoPtr<Node>
apNode(newNode);
[align=left] apNode->_data = 10;[/align]
[align=left]
[/align]
[align=left] deletep1;[/align]
[align=left]}[/align]
[align=left]//AutoPtr容易出错,因为前面的指针已经置为空,存在潜在危险,没有完全达到指针的效果,[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]//ScopedPtr 智能指针[/align]
[align=left]template<classT>[/align]
[align=left]classScopedPtr[/align]
[align=left]{[/align]
[align=left]public:[/align]
[align=left] //构造函数[/align]
[align=left] ScopedPtr(T*ptr)[/align]
[align=left] :_ptr(ptr)[/align]
[align=left] {}[/align]
[align=left] //析勾函数[/align]
[align=left] ~ScopedPtr()[/align]
[align=left] {[/align]
[align=left] if(_ptr)[/align]
[align=left] {[/align]
cout <<"delete:"<<
_ptr << endl;
[align=left] delete_ptr;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] //重载*[/align]
T&
operator*()
[align=left] {[/align]
[align=left] return*_ptr;[/align]
[align=left] }[/align]
[align=left] //operator->[/align]
T*
operator->()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left] //GetPtr[/align]
T*
GetPtr()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left]protected:[/align]
[align=left] //1.限定符为protected,不能进行拷贝,2.将拷贝构造和赋值运算符的重载声明出来[/align]
[align=left] //不能让他调用默认的,也不能在外面定义它[/align]
ScopedPtr(constScopedPtr<T>&
sp);
ScopedPtr<T>
operator=(constScopedPtr<T>&
sp);
[align=left]
[/align]
[align=left]protected:[/align]
T*
_ptr;
[align=left]};[/align]
[align=left]
[/align]
[align=left]//防止别人在类外面定义它[/align]
[align=left]//template<class T>[/align]
[align=left]//ScopedPtr<T>::ScopedPtr(const ScopedPtr<T>& sp)[/align]
[align=left]// :_ptr(sp._ptr)[/align]
[align=left]//{}[/align]
[align=left]
[/align]
[align=left]voidTestScopedPtr()[/align]
[align=left]{[/align]
ScopedPtr<int>
sp1(newint(1));
[align=left] //ScopedPtr<int> sp2(sp1);[/align]
[align=left]}[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]//SharedPtr 利用引用计数来解决这个问题[/align]
[align=left]template<classT>[/align]
[align=left]classSharedPtr[/align]
[align=left]{[/align]
[align=left]public:[/align]
[align=left] SharedPtr(T*ptr)[/align]
[align=left] :_ptr(ptr)[/align]
[align=left] , _pCount(newlong(1))[/align]
[align=left] {}[/align]
[align=left]
[/align]
[align=left] ~SharedPtr()[/align]
[align=left] {[/align]
[align=left] _Release();[/align]
[align=left] }[/align]
[align=left] //只是改变pcount[/align]
[align=left] SharedPtr(constSharedPtr<T>&sp)[/align]
[align=left] :_ptr(sp._ptr)[/align]
[align=left] , _pCount(sp._pCount)[/align]
[align=left] {[/align]
[align=left] ++(*_pCount);[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] ////赋值运算符的传统写法[/align]
//SharedPtr<T>& operator=(const
SharedPtr<T>& sp)
[align=left] //{[/align]
[align=left] // if (this != &sp)[/align]
[align=left] // {[/align]
[align=left] // this->_Release(); [/align]
// _pCount
= sp._pCount;
// _ptr =
sp._ptr;
[align=left] // ++(*_pCount);[/align]
[align=left] // }[/align]
[align=left] // return *this;[/align]
[align=left] //}[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left] //现代写法[/align]
SharedPtr<T>&
operator=(SharedPtr<T>sp)
[align=left] {[/align]
[align=left] swap(_ptr,sp._ptr);[/align]
[align=left] swap(_pCount,sp._pCount);[/align]
[align=left]
[/align]
[align=left] return*this;[/align]
[align=left] }[/align]
[align=left]
[/align]
T&
operator*()
[align=left] {[/align]
[align=left] return*_ptr;[/align]
[align=left] }[/align]
[align=left]
[/align]
T*
operator->()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left]
[/align]
T*
GetPtr()
[align=left] {[/align]
[align=left] return_ptr;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left] longGetCount()[/align]
[align=left] {[/align]
[align=left] return*_pCount;[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left]protected:[/align]
[align=left] void_Release()[/align]
[align=left] {[/align]
[align=left] //如果指向这个的引用计数为0才delete,其他时候只是前置减减[/align]
if(--(*_pCount)
== 0)
[align=left] {[/align]
[align=left] delete_ptr;[/align]
[align=left] delete_pCount;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]
[/align]
[align=left]protected:[/align]
T*
_ptr;
long*
_pCount;
[align=left]};[/align]
[align=left]
[/align]
[align=left]voidTestSharedPtr()[/align]
[align=left]{[/align]
SharedPtr<int>
sp1(newint(1));
SharedPtr<int>
sp2(sp1);
[align=left] cout << sp1.GetCount() << endl;[/align]
[align=left]
[/align]
SharedPtr<int>
sp3(newint(2));
[align=left] sp3 = sp1;[/align]
[align=left]}[/align]
相关文章推荐
- c++第2实验-项目1-标准体重
- Windows C++ Url编码
- c++作业2
- C/C++笔试常问的坑
- C++学习记录
- 浅谈C/C++的浮点数在内存中的存储方式
- C语言 百炼成钢19
- C++ 拷贝构造函数和重载赋值函数
- 用Xcode创建C++工程测试LeetCode代码
- configure: error: You need a C++ compiler for C++ support.[系统缺少c++环境]
- C++,cout和std::cout的区别
- C++之:模板元编程(三) 默认模板参数
- 静态代码检查工具的使用(cppcheck)
- Cppcheck 1.54 C/C++静态代码分析工具
- C++用钩子模仿按键精灵录制键盘鼠标的功能
- C++ 空指针调用函数 静态绑定
- P2P通讯的C++实现-UDP Hole Punching方法
- C语言文件读写操作详解
- C++的类定义中,不能在类中定义自身类的对象,java中却可以
- #if defined和#if !defined(c语言的宏定义)