C++智能指针(一)

  c++作为一种相对底层的语言,一直以来没有提供内存的自动回收技术,但是提供了很多简单的内存管理工具,帮助我们高效、安全的管理内存。其中最为重要的就是智能指针,本系列文章主要就是讲讲c++智能指针的发展与正确使用。

  今天先来讲讲最早的智能指针auto_ptr,同时也是最简单的智能指针。auto_ptr在第一版C++标准c++98中一起发布,使用简单的RAII来管理内存。用法很简单。

#include <memory>
#include <iostream>
using namespace std;
class A
{
    public:
        A(){cout<<"A construction"<<endl;}
        ~A(){cout<<"A disconstruction" <<endl;}
    void print(){cout<<"A print"<<endl;}
};
int main()
{
    std::auto_ptr<A> a(new A());
    a->print();
    return 0;
}

  需要注意的是auto_ptr所界定的是一种严格的拥有权观念,也就是说由于一个auto_ptr会删除其所管理的对象,所以这个对象绝对不能同时被其他auto_ptr“拥有”,绝对不应该出现多个auto_ptr管理一个对象的情况,auto_ptr的精彩实现使得绝大多数的情况你也做不到。但是要小心使用相同的对象来初始化两个auto_ptr的愚蠢操作。实际上auto_ptr的copy构造函数和赋值函数就是拥有权的转移。一个auto_ptr获得新的对象拥有权时候,所拥有的老对象会被删除。

std::auto_ptr<A> a(new A());
a->print();
//拥有权的转移 a不再拥有权
std::auto_ptr<A> b(a);
//拥有权的转移 b不再拥有权
std::auto_ptr<A> c=b;
std::auto_ptr<A> d(new A());

//原来拥有的对象会删除 获得新对象的拥有权   
c=d;

为了防止已经转移了拥有权的auto_ptr再次获得拥有权,auto_ptr不能通过原始指针赋值(因为copy构造函数加上了explicit),因为原始指针赋值很容易造成多个auto_ptr管理一个对象的情况。也就是说你不能写出如下的代码

A* d=new A();
std::auto_ptr<A> f=d;

但是可以通过另一个auto_ptr赋值,继续转移呗,转圈圈都可以。

  由于copy构造函数和赋值函数就是拥有权的转移,我们很容易犯类似下面这样的错误

dosomething(auto_ptr<int> _a)
{}

auto_ptr<int> temp(new int);
*temp=10;
dosomething(temp);
//错误 对象已经删除
*temp=20

  所以使用auto_ptr作为参数、返回值的时候要特别注意。一个正确的观念是 如果你不想再转移拥有权的话请使用const reference修饰。单使用reference是不对的,因为你不能保证函数里面不会出现auto_ptr temp=_a(_a是函数参数)这类转移拥有权的代码。在auto_ptr中 const reference 代表拥有权的终点,你不能再转移拥有权了,auto_ptr的源码巧妙的实现了这一点,如果你再转移一个const referenec auto_ptr的拥有权,会编译出错!

总结:

  1. auto_ptr是第一代智能指针,使用RAII方式实现。
  2. auto_ptr不能用来管理数组对象,因为其内部使用的是delete而非delete []
  3. auto_ptr所界定的是一种严格的拥有权观念,copy构造函数和赋值函数就是拥有权的转移,一个auto_ptr获得新的对象拥有权时候,所拥有的老对象会被删除。
  4. 如果要使用auto_ptr作为参数,const reference是推荐的,除非你真的要在函数中转移拥有权。
  5. 不建议在程序中使用auto_ptr,auto_ptr所代表的拥有权观念,在实际程序中并没有太多切合的使用场景。由于其还是拥有一定的复杂度,在一些可用的场景中都有更好的替代,比如本系列后面介绍的几个智能指针都可以在各个场合替代它。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值