C++智能指针系列:其二、unique_ptr

前文提到了,auto_ptr由于资源转移机制设计的不合理,有可能导致程序崩溃。在C++11中,提出了unique_ptr用以取代auto_ptr。

一、unique_ptr的设计思想

unique_ptr的设计思想和auto_ptr整体上是一致的,也是由类模板托管指针。对于资源的管理模式和auto_ptr几乎一致:一个指向堆内存的指针,最多只能同时被一个unique_ptr托管。
那么unique_ptr改进点在哪里?其核心思想就是:程序员想对不同的unique_ptr对象进行资源转移,编译器不限制。但是编译器只允许将右值unique_ptr对象的资源转移给其他对象。相当于给程序员提了个醒:这个智能指针是一个右值,一个将亡值,它的资源已经给出去了,你不要在使用它了。当然了,这也仅仅是提醒的作用,如果程序员仍然一意孤行要使用右值,那么程序崩溃是不可避免的。
相对于auto_ptr,unique_ptr主要做了这两件事情:
(1)禁用拷贝构造函数,和参数为左值的赋值运算符重载函数。
(2)实现移动构造函数,和参数为右值的赋值运算符重载函数。
多说一句,unique_ptr相对于auto_ptr,支持了对数组的托管,但是个人感觉这个功能过于鸡肋,不再赘述。

二、自己实现的unique_ptr

有了基本思想,我们大可以自己实现一个unique_ptr:

template<typename Ty>     //Ty是被托管的指针类型
class my_ptr{
private:
    Ty * ty;     //被托管的指针
public:
    explicit my_ptr(Ty * ty1=0):ty(ty1){}

    ~my_ptr(){delete ty;}    //析构函数中释放资源

    Ty * get(){          //返回被托管的指针
        return ty;
    }

    Ty * release(){       //转移被托管的指针
        Ty * temp = ty;
        ty = 0;
        return temp;
    }

    void reset(Ty * ty2){      //重置被托管的指针
        delete ty;
        ty = ty2;
    }

    Ty * operator ->(){       //重载->和*运算符,让智能指针用起来像指针
        return ty;
    }

    Ty & operator * (){
        return *(ty);
    }

    my_ptr(my_ptr && ty1){     //移动构造函数
        this->ty = ty1.release();
    }

    my_ptr& operator = (my_ptr && ty1 ){   //移动赋值运算符重载
        reset(ty1.release());
        return *this;
    }

    my_ptr& operator = (my_ptr & ty1 ) = delete; //禁用左值赋值运算符重载

    my_ptr(my_ptr & ty1) = delete; //禁用左值拷贝构造函数
};

具体用法:

class Test {
public:
    Test() { cout << "Test start..." << endl; }
    ~Test() { cout << "Test end..." << endl; }
    int getDebug() { return this->debug; }
private:
    int debug = 20;
};

void my_ptr_test(my_ptr<Test> ptr) {}

int main ( )
{
    my_ptr<Test> ptr1(new Test);
    //my_ptr<Test> ptr2(ptr1); 错误,拷贝构造函数被禁用了
    my_ptr<Test> ptr2(move(ptr1));
    
    my_ptr<Test> ptr3;
    //ptr3 = ptr2; 错误,左值运算符重载被禁用了。
    ptr3 = move(ptr2);
    
    //my_ptr_test(ptr3); 错误,不允许以左值的形式给形参赋值
    my_ptr_test(move(ptr3));
    cout<< ptr3.get();
}

但是,这个解决方案还是略显治标不治本。只是通过一个move函数提醒程序员,慎重考虑资源转移的问题。根本原因是前面两种智能指针的设计模式就是资源独占。那么有没有更好的解决方法?请看下一篇。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值