智能指针的原理和简单实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了智能指针的原理和简单实现相关的知识,希望对你有一定的参考价值。
什么是智能指针?
智能指针实质上是一个类,定义一个类来封装资源的分配和释放。这个类的构造函数中传入一个指针,完成资源的分配和初始化。在析构函数中释放传入的该指针,完成资源的释放。
为什么要用智能指针?
智能指针就是智能,自动化的管理指针所指向的动态资源。
例如以下情况:代码中经常会忘记释放动态开辟的内存资源,导致内存泄露。
// case1 void Test2() { int* p1 = new int(2); bool isEnd = true; //... if (isEnd) { delete p1; return; } //... delete p1; } // case2 void DoSomeThing() { //... throw 2; //... } void Test2() { int* p1 = new int(2); //... try { DoSomeThing(); } catch (...) { delete p1; throw; } //... delete p1; }
智能指针的简单实现。
Auto_ptr:不能共享所有权,只要出现两个指针指向同一块资源,就释放前一个指针的管理权。保证只有一个指针指向一块资源。
Scoped_ptr:将类中的成员函数拷贝构造和赋值运算符只申明为protected,不定义。所以不可能有两个指针指向同一个对象。
Shared_ptr:采用引用计数的方法。将一个计数器与类指向的对象相关联,引用计数跟踪共有多少个类对象共享同一指针。
ScopedArray和Scoped_ptr类似,只是操作的是数组。SharedArray同理。
template <class T> class AutoPtr { public: AutoPtr(T*ptr) :_ptr(ptr) {} AutoPtr( AutoPtr<T>&ap) :_ptr(ap._ptr) { ap._ptr = NULL; } AutoPtr<T>&operator=(const AutoPtr<T>&ap) { if (this != &ap) { delete _ptr; _ptr = ap._ptr; ap._ptr = NULL; } } ~AutoPtr() { if (_ptr) { delete _ptr; _ptr = NULL; } } T&operator*() { return *_ptr; } T*operator->() { return _ptr; } T*GetPtr() { return _ptr; } protected: T*_ptr; }; struct Node { int _data; Node*_next; }; void Test_AutoPtr() { int*p1 = new int(2); int*p2 = p1; int*p3 = p2; *p3 = 10; delete p1; AutoPtr<int>ap1(new int(2)); AutoPtr<int>ap2=ap1; //此时ap1为NULL,无管理权 AutoPtr<int>ap3(ap2); //此时ap2为NULL,无管理权 //*ap2 = 10; //程序崩溃 *ap3 = 10; AutoPtr<Node>sp1(new Node); sp1->_data = 10; } template<class T> class ScopedPtr { public: ScopedPtr(T*ptr) :_ptr(ptr) {} ~ScopedPtr() { if (_ptr) { delete _ptr; _ptr = NULL; } } T&operator*() { return *_ptr; } T*operator->() { return _ptr; } T*GetPtr() { return _ptr; } protected: //只申明,不定义,防止拷贝构造和赋值运算符重载。 ScopedPtr(const ScopedPtr<T>&sp); //保护,防止在外定义。若写为public,则有可能在类外定义。 ScopedPtr<T>& operator=(const ScopedPtr<T>&sp); protected: T*_ptr; }; void Test_ScopedPtr() { ScopedPtr<int>sp1(new int(3)); //ScopedPtr<int>sp2(sp1); //protectd:无法访问 } template <class T> class ScopedArray { public: ScopedArray(T*ptr) :_ptr(ptr) {} ~ScopedArray() { if (_ptr) { delete[]_ptr; } } T&operator[](size_t Index) { return _ptr[Index]; } T&operator*() { return *_ptr; } T*operator->() { return _ptr; } T*GetPtr() { return _ptr; } protected: ScopedArray(const ScopedArray<T>&sp); ScopedArray<T>&operator=(const ScopedArray<T>&sp); protected: T*_ptr; }; void Test_ScopedArray() { ScopedArray<int>sp1(new int[5]); //ScopedPtr<int>sp2(sp1); } template <class T> class SharedPtr { public: SharedPtr(T*ptr) :_ptr(ptr) , _Pcount(new long(1)) {} SharedPtr(const SharedPtr<T>&sp) :_ptr(sp._ptr) , _Pcount(sp._Pcount) { ++*(_Pcount); } //SharedPtr<T>&operator=(const SharedPtr<T>&sp) //传统写法 //{ // if (this != &sp) // { // if (--(*_Pcount) == 0) // { // delete _ptr; // delete _Pcount; // } // _ptr = sp._ptr; // _Pcount = sp._Pcount; // ++(*_Pcount); // } // return *this; //} SharedPtr<T>&operator=(const SharedPtr<T>sp) //现代写法 { swap(_ptr, sp._ptr); swap(_Pcount, sp._Pcount); return *this; } ~SharedPtr() { if (--(*_Pcount) == 0) { delete _ptr; delete _Pcount; } } T&operator*() { return *_ptr; } T*operator->() { return _ptr; } T*GetPtr() { return _ptr; } long GetCount() { return *_Pcount; } protected: T*_ptr; long*_Pcount; }; void Test_SharedPtr() { SharedPtr<int>sp1(new int(2)); SharedPtr<int>sp2(sp1); } template <class T> class SharedArray { public: SharedArray(T*ptr) :_ptr(ptr) , _Pcount(new long (1)) {} SharedArray(const SharedArray<T>&sp) :_ptr(sp._ptr) , _Pcount(sp._Pcount) { ++*(_Pcount); } SharedArray<T>&operator=(const SharedArray<T>sp) //现代写法 { swap(_ptr, sp._ptr); swap(_Pcount, sp._Pcount); return *this; } ~SharedArray() { if (--(*_Pcount) == 0) { delete[] _ptr; delete _Pcount; } } T&operator*() { return *_ptr; } T*operator->() { return _ptr; } T*GetPtr() { return _ptr; } T&operator[](size_t Index) { return _ptr[Index]; } long GetCount() { return *_Pcount; } protected: T*_ptr; long*_Pcount; }; void Test_SharedArray() { SharedArray<int>sp1(new int[5]); SharedArray<int>sp2(sp1); }
本文出自 “printf的返回值” 博客,请务必保留此出处http://10741125.blog.51cto.com/10731125/1782624
以上是关于智能指针的原理和简单实现的主要内容,如果未能解决你的问题,请参考以下文章