STL学习笔记 ---- 神秘的auto_ptr

作者:winterTTr(转载请注明) 资料来源:《STL标准库》

 

 

为什么说它神秘呢,那好吧,我可以换一个更直白的词语,那就是“陷阱重重”。

对于不了解auto_ptr的人来说,使用它就是一种灾难,而避免这种灾难,就必须揭开它神秘的面纱,了解其内部运作机制。

 

 

 

  • 为什么要出现auto_ptr
  • 看这样一段代码,如果中间的操作出现异常,或者出现return,我们将会忘记释放ptr这个变量的空间,这无疑会造成内存泄露。而这种泄露往往可能是我们不经意的。那么,auto_ptr的出现,就是为了解决这种问题而出现的。他利用局部变量离开作用域会释放的原则,将主动申请的资源指针放置于其内部,并在其析构的时候,释放掉资源。由于auto_ptr本身是局部变量,就保证了主动申请的资源能够在离开作用域的时候被及时合理的释放。同时,即便是异常的出现,也不会造成内存的泄露。

    好, 我们重写上面的代码:

     

    当然,auto_ptr重载了*和->操作符,我们能像正常使用原始指针一样,去使用这个变量。

     

    使用的注意点:

    1.指针的计算操作(例如:++)是没有 被定义的

    2.auto_ptr不允许使用原始指针进行赋值操作,只能使用原始指针进行构造函数的初始化。

    也就是说:

    std::auto_ptr<ClassA> ptr1(new ClassA); //OK
    std::auto_ptr<ClassA> ptr2 = new ClassA; //ERROR

     

     

  • auto_ptr的神秘面纱:拥有权的转移
  • 拥有权(Ownership)是auto_ptr最重要的概念之一。对于一个auto_ptr来说,它会主动释放它所拥有的资源。所以,对于资源的拥有权应该是唯一的。在同一时间,一个资源应该只能被一个auto_ptr所拥有(否则可能会造成double delete的crash)。

    那么,涉及到一个很重要的注意点:auto_ptr的拷贝构造函数和赋值操作符,是如何动作的呢。

     

    看这样的代码,在进行copy construct之后,ClassA的资源,实际上已经被转移到ptr2中了,那么ptr1呢?!这点非常关键(同时所引起的问题也是致命的),ptr1内部,实际上已经是空指针了!!ptr1不在拥有(释放了)对资源的拥有权(保证拥有权的唯一性)。

    同理,赋值操作符也是进行同样的操作。这便是auto_ptr最神秘的面纱~~

     

  • auto_ptr的在函数调用中的情况
  • 1. 传值方式的函数调用:会将拥有权传入函数内部,同时函数执行结束后,会释放资源。

    2. 返回值方式的函数调用:会将函数申请的资源返回caller,caller退出后,将会释放资源。

     

  • 注意点
  • 1.不要随便使用传值方式的auto_ptr函数调用,因为这样会释放你的资源

    2.企图使用引用方式的函数调用,可能会在函数内部被赋值操作转移拥有权,这是很不好的调用方式。

    3.使用const的引用方式,可以减少无意识的拥有权转移的问题。

    4.对于const方式的引用,其实可能更像是一个T* const p,而不是const T* p

     

  • 有关auto_ptr的使用事项
  • 1.一定不要使用auto_ptr共享一个资源的拥有权

    2.不能使用auto_ptr存储数组指针,因为只有auto_ptr执行的是delete对,而不是delete []

    3.auto_ptr不是被设计为引用计数的智能指针,所以,不要试图按照这种想法去使用

    4.auto_ptr是不能被STL中的标准容器使用的,因为其中的赋值操作,会转移ownership,这会造成意想不到的问题。

     

  • auto_ptr的内幕
  • 值得注意的是,reset函数执行的操作,是先delete内部资源,再重新获得新的资源。

    get()不改变拥有权,release()会放弃拥有权(赋值NULL)

     

    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 1
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论 1
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值