浅谈智能指针

来源:互联网 发布:北京java培训那好 编辑:程序博客网 时间:2024/06/05 19:09

      在代码中,经常会忘掉释放动态开辟的资源,即使再小心,也会不小心忘记释放,导致内存泄漏。故而引出智能指针。

      首先,提出一个概念

RAII(Resource Acquisition Is Initialization):资源分配即初始化,是管理资源、避免内存泄露的方法。方法是:定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的的清理,可以保证资源的正确初始化和释放。

     C++库中有有多种智能指针,本文将模拟部分智能指针的实现。

          1.AutoPtr-----管理权转移

template<typename T>class AutoPtr{public:AutoPtr(T* ptr):_ptr(ptr){}AutoPtr(AutoPtr<T>& ap):_ptr(ap._ptr){ap._ptr = NULL;}AutoPtr<T>& operator = (AutoPtr<T>& ap){if (this != &ap){delete _ptr;_ptr = ap._ptr;ap._ptr = NULL;}return *this;}~AutoPtr(){if (_ptr){delete _ptr;}}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}protected:T* _ptr;};
但是这种方法是不可取的,故在C++11中又引出了其他智能指针
          2.ScopedPtr------防拷贝
template<typename T>class ScopedPtr{public:ScopedPtr(T* ptr):_ptr(ptr){}~ScopedPtr(){delete _ptr;}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}protected:ScopedPtr(const ScopedPtr<T>& sp);ScopedPtr<T>& operator=(const ScopedPtr<T>& sp);protected:T* _ptr;};
该智能指针是只对拷贝构造函数和赋值运算符重载进行声明,不对其进行定义。但是其运用的场景并不是很广泛。
          3.SharePtr------引用计数
template<typename T>class SharedPtr{public:SharedPtr(T* ptr):_ptr(ptr),_refCount(new int(1)){}SharedPtr(SharedPtr<T>& sp):_ptr(sp._ptr),_refCount(sp._refCount){++(*_refCount);}SharedPtr<T>& operator=(SharedPtr<T>& sp){if (this != &sp){this->Release();this->_ptr = sp._ptr;this->_refCount = sp._refCount;++(*_refCount);}return *this;}~SharedPtr(){Release();}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}void Release(){if (--(*_refCount) == 0){delete _ptr;delete _refCount;}}protected:T* _ptr;int* _refCount;};
该智能指针的优点是:功能强大,使用场景多。缺点是:过于复杂,且会造成循环引用。
弱指针weak_ptr可以解决循环引用。



1 0
原创粉丝点击