智能指针

来源:互联网 发布:土门离比客运站源码 编辑:程序博客网 时间:2024/05/16 19:02

智能指针其实是一种类,体系。智能指针不等同于RAII。智能指针是RAII的一种应用,智能管理释放,能够像指针一样使用。正常赋值拷贝(解决多个智能指针对象管理同一块资源释放多次的问题)。

首先来看C++早期智能指针auto_ptr的模拟实现:

#include<iostream>using namespace std;template<class T>class Auto_ptr{public:Auto_ptr(T* ptr = NULL):_ptr(ptr){}~Auto_ptr(){cout << _ptr << endl;delete[]_ptr;}T& operator*(){return *_ptr;}T& operator->(){return _ptr;}protected:T* _ptr;AA;};struct AA{int _a1;int _a2;};void F1(){int*p1 = new int;Auto_ptr<int> ap1(p1);cout << *p1 << endl;*ap1 = 20;*p1 = 10;cout << *ap1 << endl;Auto_ptr<AA>ap2(new AA);AA* p2 = new AA;(*p2)._a1 = 10;(*p2)._a2 = 20;p2->_a1 = 30;p2->_a2 = 40;}int main(){try{F1();}catch (exception& e){cout << e.what() << endl;}system("pause\n");return 0;}
但是这个程序是有问题的,因为当它运行Auto_ptr<int>ap2=ap1时程序会崩溃,因为它存在浅拷贝问题(当调用析构函数的时候会析构两次),那如何解决这个问题呢,我们可以实现管理权的转移:

Auto_ptr(Auto_ptr<T>& ap):_ptr = (ap._ptr){ap._ptr = NULL;}
还有一种解决此方法的智能指针shared_ptr,它的原理是,当有赋值运算符和拷贝构造时,两个或者两个以上的参数共同来通过引用计数来管理该空间,只有当引用计数是0的时候才调用析构函数,模拟实现该智能指针:

#include<iostream>using namespace std;template <class T>class Shared_ptr{public:Shared_ptr(T* ptr); _ptr(ptr), _countRef(1){}Shared_ptr(const Shared_ptr<T>& sp){_ptr(sp._ptr);_countRef = sp._countRef;{++*_countRef;}}~Shared_ptr(){Release();}void Release(){if (--(*_countRef) == 0){cout << _ptr << endl;delete _ptr;}delete _countRef;}int Usecount()//查看有多少管理着这个空间{return *_countRef;}Shared_ptr<T>& operator=(const Shared_ptr<T>& sp){if (_ptr != sp._ptr){Release;_ptr = sp._ptr;_countRef = sp._countRef;++(*_countRef);}return *this;}protected:T* _ptr;int* _countRef(new int(1));};int main(){Shared_ptr<int>sp4(new int(20));Shared_ptr<int>sp1(new int(10));Shared_ptr<int>sp2(sp1);sp1 = sp4;sp2 = sp4;return 0;}

另外一种我们经常使用的智能指针是Scopted_ptr,它的设计理念是:1,将拷贝构造和赋值运算符的重载只是进行申明,但不定义。2,申明的时候要申明成私有成员。这样做的目的是:申明的时候是为了能在类外面使用,不进行定义是为了早类外使用时不实现将前一个指针的地址赋值给后一个指针

它的实现原理是:

template<class T>class ScopedPtr{public:ScopedPtr(T* ptr = NULL):_ptr(ptr){}~ScopedPtr(){if (_ptr){delete _ptr;}}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}private:ScopedPtr(const ScopedPtr<T>& sp);ScopedPtr<T>& operator=(const ScopedPtr<T>&);protected:T* _ptr;};






原创粉丝点击