智能指针auto_ptr的实现

auto_ptr实现原理是资源管理权的转移,即是说构造函数创建对象时获得资源管理权,析构对象时撤销管理权,这样的管理权的转移,带来的最重要的缺点就是安全性问题,下面具体阐述一下新旧版本的auto_ptr方便理解。
模拟实现旧版本的auto_ptr:
旧版本的auto_ptr是多定义了一个成员对象_symbol来标识该成员对象的资源管理权,在调用构造函数创建对象时获得资源管理权,即_symbol置为true,在调用拷贝构造函数、赋值运算符重载、析构函数时将其值为false.

#include<iostream>
using namespace std;
template<class T>
class Autoptr
{
public:
    Autoptr<T>(T*ptr = NULL)
        :_ptr(ptr)
        , _symbol(true)

    {}
    Autoptr<T>(const Autoptr<T>&a)
        :_ptr(a._ptr)
        , _symbol(true)
    {
        a._symbol = false;
    }
    Autoptr<T>&operator=(const Autoptr<T>&a)
    {
        if (this != &a)
        {
            delete this->_ptr;
            _ptr = a._ptr;
            _symbol = ture;
            a._symbol = false;
        }
        return *this;
    }
    T&operator*()//解引用操作符重载
    {
        return *(this->_ptr);
    }
    T&operator*()const//const型解引用操作符重载
    {
        return  *(this->_ptr);
    }
    T*operator->()//取地址操作符重载
    {
        return this->_ptr;
    }
    T*operator->()const//const型取地址操作符重载
    {
        return this->_ptr;
    }
    ~Autoptr<T>()
    {
        if (_ptr)
        {
            delete _ptr;
            _symbol = false;
        }
    }
private:
    T* _ptr;
    mutable bool _symbol;//在const修饰的成员函数中要对类的某个数据成员进行修改,该数据成员定义声明必须加mutale关键字。
};
int main()
{
    Autoptr<int>p1(new int);//
    int i = 1;
    if (i == 1)
    {
        Autoptr<int>p2(p1);
    }
    *p1 = 10;
    system("pause");
    return 0;

}

这里写图片描述
原因是:p2出了if作用域会释放,将自己的空间释放,当再次为p1赋值将导致寻址失败,而导致程序崩溃。

新版的auto_ptr的实现:
继承旧版的auto_ptr实现的思想,将symbol去掉,在使用拷贝构造、赋值运算符重载后直接将原对象置空。

//新版
template<class T>
class Auto_ptr
{
public:
        Auto_ptr(T*ptr=NULL)
               : _ptr(ptr)
        {}
        Auto_ptr( /*const*/ Auto_ptr<T>&a)
               :_ptr(a._ptr)
        {
               a._ptr = NULL;
        }
        Auto_ptr<T>&operator=(const Auto_ptr<T>&a)
        {
               if (this != &a)
               {
                       delete _ptr;
                       _ptr = a._ptr;
                       a._ptr = NULL;
               }
               return *this;
        }
        T&operator*()//解引用操作
        {
               return *(this->_ptr);
        }
        T&operator*()const//解引用操作
        {
               return *(this->_ptr);
        }
        T*operator->()//取地址操作
        {
               return this->_ptr;
        }
        T*operator->()const//const取地址操作
        {
               return this->_ptr;
        }
        ~Auto_ptr<T>()
        {
               if (_ptr)
               {
                       delete _ptr;
                       _ptr = NULL;
               }
        }
private:
        T* _ptr;
};
int main()
{
        Auto_ptr<int> p(new int(1));
        Auto_ptr<int> p1(p);
        Auto_ptr<int> p2 = p1;
        *p= 10;//这样就会报错误。
        system("pause");
        return 0;
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/xiaodu655/article/details/81392774