智能指针auto_ptr

  • 设计 auto_ptr目的    

auto_ptr是一种智能型指针,帮助程序员防止“被异常抛出时发生资源泄露”。auto_ptr只是针对某个特定问题而设计,对于其他问题,auto_ptr无能为力。

        如果一开始获取的资源被绑定于局部对象,那么当函数执行完毕退出时,它们的析构函数被调用,从而自动释放这些资源。然而如果资源是以显式方法获得,而且没有被绑定在任何对象身上,那么必须以显式方法释放。

比如用new和delete来产生和销毁对象:

void foo()
{
    ClassA *ptr = new ClassA;
    ...
    delete ptr;
}

        使用new创建一个新对象并在函数结束时用delete释放掉,这样函数会顺利结束并且不会存在内存泄露的问题。但是有时我们会忘记写delete而引发问题,同时如果在函数中间存在return语句时会引发更大问题。异常一旦出现,函数将立刻退出,根本不会调用函数尾端的delete语句,这样就会造成内存遗失。

解决这个问题的常用办法是捕捉异常

void foo()
{
    ClassA* ptr = new ClassA;
    try
    {
        ...  //perform some operation
    }
    catch (...)
    {
        //for any exception    
        delete ptr;
        throw;
    }

    delete ptr;
}

为了在异常发生时处理对象的删除工作,代码将会变得很繁琐,如果有多个对象,则需要对每一个对象都执行此操作。

如果使用智能型指针来解决此问题就会非常简单。这个智能型指针应保证无论在何种情形下只要自己被摧毁,就一定连带释放其所指资源。而由于智能型指针本身就是局域变量,所以无论是正常退出还是异常退出,它就一定会被销毁。

auto_ptr就是这种指针:它是“它所指对象”的拥有者,同时auto_ptr要求一个对象只能有一个拥有者。

#include<memory>
void foo()
{
    std::auto_ptr<ClassA> ptr(new ClassA);
    ...
}

auto_ptr<>不允许使用一般指针惯用的赋值初始化方式,必须直接使用数值来完成初始化

std::auto_ptr<ClassA> ptr1(new ClassA);   //ok
std::auto_ptr<ClassA> ptr2 = new ClassA;  //ERROR
  • auto_ptr拥有权的转移

        auto_ptr界定的是一种严格的拥有权观念,绝对不允许出现多个auto_ptr同时拥有一个对象的情况。

        这个条件导致了一个问题:auto_ptr的拷贝构造函数和赋值操作符应该怎样运行呢?

        解决办法是:令auto_ptr的拷贝构造函数和赋值操作符将对象拥有权交出去。

//初始化
std::auto_ptr<ClassA> ptr1(new ClassA);


//拷贝构造函数
std::auto_ptr<ClassA> ptr2(ptr1);


//赋值操作
std::auto_ptr<ClassA>ptr2;
ptr2=ptr1;

        在第一个语句中,ptr1拥有了那个new出来的对象,在第二语句中,拥有权由ptr1转交给ptr2。此后ptr2就拥有了那个new出来的对象,而ptr1不再拥有它。

        第三个赋值语句也是同样的道理,需要注意的是如果ptr2被赋值之前拥有另外一个对象,执行赋值操作时首先会调用delete,先将ptr2指向的对象删除掉然后再将ptr1赋值给ptr2。

        这里我们还需要注意一个问题就是,只要发生了拥有权转移,先前的拥有者就失去了拥有权,这时它只剩了一个NULL指针。那么如何保证使用者重新解引用这个空指针呢?auto_ptr规定只能使用auto_ptr作为另外一个auto_ptr的初值,普通指针不可以。

  • auto_ptr的起点和终点

       拥有权的转移使得某个函数可以利用auto_ptr将拥有权转交给另一个函数,可能会出现两种情况:

        ①某函数是数据的终点。如果auto_ptr以传值的方式被当作一个参数传递给某函数,此时被调用端的参数获得了这个auto_ptr的拥有权,如果函数不再将它传递出去,它所指的对象就会在函数退出时被删除。

        ②某函数是数据的起点。当一个auto_ptr被返回,其拥有权便被转交给调用端了。

考虑到auto_ptr的概念,可以用const reference像函数传递拥有权,这里的const并非意味不能更改auto_ptr所拥有的对象,而是意味着不能更改auto_ptr的拥有权。 

  • auto_ptr的错误使用

        ①auto_ptr之间不能共享拥有权

一个auto_ptr不能指向另一个auto_ptr所拥有的对象,否则,当第一个指针删除该对象后,另一个指针就会指向一个已经被销毁的对象,此时如果再使用那个指针进行读写操作,就会引发错误。

        ②不存在针对array而设计的auto_ptr

auto_ptr不可以指向array,因为auto_ptr是通过delete而不是delete[ ]来释放其所拥有的对象。

        ③auto_ptr并不是一个全能的、“四海通用”型的指针

并非任何适用智能型指针的地方,都适用auto_ptr。

        ④auto_ptr不满足STL容器对其元素的要求

由于在拷贝和赋值动作之后,原本的auto_ptr和新产生的auto_ptr并不相等。原本的auto_ptr会交出拥有权,而不是拷贝给新的auto_ptr。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值