浅谈c++智能指针
来源:互联网 发布:伴奏制作软件 编辑:程序博客网 时间:2024/06/05 02:06
所谓的智能指针就是智能/自动化的管理指针所指向的动态资源的释放。
智能指针的产生是由于C++没有内存的自动回收机制,每次new出来的空间都需要收到的delete,而在个别情况下,总是无法及时的delete,或者异常导致程序提早退出,造成内存泄漏。于是弥补上述不足的智能指针应用而生。
智能指针的发展可分为三个阶段
(1)auto_ptr c++98
(2)scoped_ptr/shared_ptr/weak_ptr boost库
(3)unique_ptr/shared_ptr/weak_ptr c++11
设计思想
auto_ptr实际上是管理权限的转移,此设计本身带有缺陷,不宜使用。
template<class T> class Auto_ptr { public: Auto_ptr(T* ptr) :_ptr(ptr) {} Auto_ptr(Auto_ptr<T>& ap) { ap._ptr = NULL; } Auto_ptr<T>& operator=(Auto_ptr<T>& ap) { if(_ptr != ap._ptr) { delete _ptr; _ptr = NULL; _ptr = ap._ptr; ap._ptr = NULL; } return *this; } ~Auto_ptr() { if(_ptr) { delete _ptr; } } T* operator->() { return _ptr; } T& operator*() { return *_ptr; } private: T* _ptr; };
通过管理权的转移,避免了同一块空间被释放两次,的问题,但同时,原有指针也失去了对该空间的操作权限,所以不建议使用该方法。
scoped_ptr又叫 守卫指针,用来防止拷贝,可以解决Auto_ptr的问题。
解决的方法:
(1)拷贝构造和赋值运算符的操作可以只声明,不定义。
(2)将声明为私有,防止定义。
template<class T>class Scoped_ptr{public:Scoped_ptr(T* ptr) :_ptr(ptr) {} ~Scoped_ptr() { if(_ptr) { delete _ptr; } } T* operator->() { return _ptr; } T& operator*() { return *_ptr; }private:Scoped_ptr<T>& operator=(Scoped_ptr<T>& sp);Scoped_ptr(Scoped_ptr<T>& sp); private:T* _ptr;};指针功能明显受到限制,后来人们就不用了;于是行的智能指针诞生了。
shared_ptr采用了引用计数的思想,为需要拷贝和福祉的指针开启另一个空间。
temeplate<class T>class Shared_ptr{public:Shared_ptr(T* ptr) :_ptr(ptr) ,_ref(new int(1)) {}Shared_ptr(Shared_ptr<T>& sp) :_ptr(sp.ptr) ,_ref(sp.ref){ (*_ref)++;} Shared_ptr<T>& operator=(Shared_ptr<T>& sp){if(_ptr != sp._ptr){if(--(*_ref) == 0){delete _ptr;deelte _ref;} delete _ptr; _ptr = sp._ptr; _ref = sp._ref; (*_ref)++;}return *this;}~Shared_ptr(){if(--(*_ref)==0){delete _ptr;delete _ref;}}T* operator->(){return _ptr;}T& operator*(){return _*ptr;}int Getref(){return *_ref} T* Getptr(){return _ptr;}protected:T* _ptr;int* _ref;};
上面的代码虽然简单的实现引用计数版的简化版智能指针Shared_ptr;但是存在着一下问题,
(1)引用计数更新存在着线程安全。
(2)循环引用的问题。
(3)定制删除器。
解决循环引用的问题,需要一个弱指针。
struct ListNode{ //WeakPtr<ListNode> _prev; //WeakPtr<ListNode> _next; SharedPtr<ListNode> _prev; SharedPtr<ListNode> _next; ~ListNode() { cout << "~ListNode()" << endl; }};void TestCycleRef(){ SharedPtr<ListNode> cur = new ListNode; SharedPtr<ListNode> next = new ListNode; cout << "cur->Coun t:" << cur.RefCount() << endl; cout << "next->Coun t:" << next.RefCount() << endl; cur->_next = next; next->_prev = cur; cout << "cur->Coun t:" << cur.RefCount() << endl; cout << "next->Coun t:" << next.RefCount() << endl;}
cur与next的引用计数均为2,且均无法释放,改为weak_ptr,(不增加引用计数)
template<class T>class WeakPtr{public: WeakPtr() :_ptr(NULL) {} WeakPtr(const SharedPtr<T>& sp) :_ptr(sp.GetPtr()) {} T& operator*() { return *_ptr; } T* operator->() { return _ptr; }protected: T* _ptr;};
如此解决了循环引用的问题。
阅读全文
1 0
- 【C++】浅谈boost库智能指针
- C++智能指针浅谈
- 浅谈智能指针
- 浅谈RAII&智能指针
- 浅谈智能指针
- 浅谈auto_ptr智能指针
- 浅谈智能指针
- 浅谈智能指针shared_ptr
- 浅谈C++智能指针
- 浅谈c++智能指针
- 浅谈auto_ptr智能指针
- 浅谈C++的智能指针
- 浅谈C++的智能指针
- 浅谈C++的智能指针
- 浅谈C++的智能指针
- 浅谈C++的智能指针
- 浅谈C++的智能指针
- c++:智能指针
- java日期,时间比较
- 数据交换
- SPOJ VLATTICE
- gcc 和 nasm的区别
- Java 内存区域和GC机制
- 浅谈c++智能指针
- 【Node.js-2】自定义模块以及引用、自定义模块存放路径、发布升级自定义的模块
- 【NOIP2017】Day2
- java中list去重复
- hdu6075Questionnaire(高校第四场)
- Json相关随笔
- The Suspects POJ
- tensorflow——tf.one_hot以及tf.sparse_to_dense函数
- thread和runable的区别