C++智能指针 auto_ptr

auto_ptr 是一个轻量级的智能指针, 定义于 memory (非memory.h)中, 命名空间为 std.
auto_ptr 适合用来管理生命周期比较短或者不会被远距离传递的动态对象, 最好是局限于某个函数内部或者是某个类的内部.

使用方法:
  std::auto_ptr<int> pt(new int(10));
  pt.reset(new int(11));

成员函数

  3个重要的函数:
  (1) get 获得内部对象的指针, 由于已经重载了()方法, 因此和直接使用对象是一样的.如 auto_ptr <int> sp(new int(1)); sp 与 sp.get()是等价的
  (2) release 放弃内部对象的所有权,将内部指针置为空, 返回所内部对象的指针, 此指针需要手动释放
    std::auto_ptr<int> ap0(new int(1));
    int* pa = ap0.release();
    delete pa; // 需要手动释放
  (3) reset 销毁内部对象并接受新的对象的所有权(如果使用缺省参数的话,也就是没有任何对象的所有权)

  其构造函数被声明为 explicit, 因此不能使用赋值符对其赋值(即不能使用类似这样的形式 auto_ptr<int> p = new int;)

auto_ptr 的特征

(1) auto_ptr 的对象所有权是独占性的.
  auto_ptr 的拷贝构造和赋值操作符所接受的参数类型都是非const的引用类型(而一般都应该使用的const引用类型), 其原因在于为了使其内部能调用了 release 方法将原有的对象进行释放, 然后使用新对象替换原有的对象.
  因此导致动态对象的所有权被转移了, 新的 auto_ptr 独占了动态对象的所有权. 被拷贝对象在拷贝过程中被修改, 拷贝物与被拷贝物之间是非等价的.
  下面的使用方法将会出错:
    std::auto_ptr<int> pt1(new int(10));
    std::auto_ptr<int> pt2 = pt1;
    printf("pt1:%d\n", pt1); // 此时应输出 0
    printf("pt1 value:%d\n", *pt1); // 错误, 对象已释放
(2) 不能将 auto_ptr 放入到标准容器中. 标准库容器无准备的拷贝行为, 会导致原 auto_ptr 内的对象被释放, 造成难以发觉的错误.

使用 auto_ptr 的注意事项

(1) auto_ptr 不能指向数组
(2) auto_ptr 不能共享所有权
(3) auto_ptr 不能通过复制操作来初始化
(4) auto_ptr 不能放入容器中使用
(5) auto_ptr 不能作为容器的成员
(6) 不能把一个原生指针给两个智能指针对象管理(对所有的智能指针).
  int* p = new int;
  auto_ptr<int> ap1(p);
  auto_ptr<int> ap2(p); // 错误, p不能给第二个智能指针对象. 会引起两次释放p

VC中的源码实现

template<class _Ty>
class auto_ptr
{ // wrap an object pointer to ensure destruction
public:
typedef auto_ptr<_Ty> _Myt;
typedef _Ty element_type; explicit auto_ptr(_Ty *_Ptr = ) _THROW0()
: _Myptr(_Ptr)
{ // construct from object pointer
} auto_ptr(_Myt& _Right) _THROW0()
: _Myptr(_Right.release())
{ // construct by assuming pointer from _Right auto_ptr
} auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()
{ // construct by assuming pointer from _Right auto_ptr_ref
_Ty *_Ptr = _Right._Ref;
_Right._Ref = ; // release old
_Myptr = _Ptr; // reset this
} template<class _Other>
operator auto_ptr<_Other>() _THROW0()
{ // convert to compatible auto_ptr
return (auto_ptr<_Other>(*this));
} template<class _Other>
operator auto_ptr_ref<_Other>() _THROW0()
{ // convert to compatible auto_ptr_ref
_Other *_Cvtptr = _Myptr; // test implicit conversion
auto_ptr_ref<_Other> _Ans(_Cvtptr);
_Myptr = ; // pass ownership to auto_ptr_ref
return (_Ans);
} template<class _Other>
_Myt& operator=(auto_ptr<_Other>& _Right) _THROW0()
{ // assign compatible _Right (assume pointer)
reset(_Right.release());
return (*this);
} template<class _Other>
auto_ptr(auto_ptr<_Other>& _Right) _THROW0()
: _Myptr(_Right.release())
{ // construct by assuming pointer from _Right
} _Myt& operator=(_Myt& _Right) _THROW0()
{ // assign compatible _Right (assume pointer)
reset(_Right.release());
return (*this);
} _Myt& operator=(auto_ptr_ref<_Ty> _Right) _THROW0()
{ // assign compatible _Right._Ref (assume pointer)
_Ty *_Ptr = _Right._Ref;
_Right._Ref = ; // release old
reset(_Ptr); // set new
return (*this);
} ~auto_ptr()
{ // destroy the object
delete _Myptr;
} _Ty& operator*() const _THROW0()
{ // return designated value
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myptr == )
_DEBUG_ERROR("auto_ptr not dereferencable");
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */ return (*get());
} _Ty *operator->() const _THROW0()
{ // return pointer to class object
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myptr == )
_DEBUG_ERROR("auto_ptr not dereferencable");
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */ return (get());
} _Ty *get() const _THROW0()
{ // return wrapped pointer
return (_Myptr);
} _Ty *release() _THROW0()
{ // return wrapped pointer and give up ownership
_Ty *_Tmp = _Myptr;
_Myptr = ;
return (_Tmp);
} void reset(_Ty *_Ptr = )
{ // destroy designated object and store new pointer
if (_Ptr != _Myptr)
delete _Myptr;
_Myptr = _Ptr;
} private:
_Ty *_Myptr; // the wrapped object pointer
};

C++智能指针 auto_ptr的更多相关文章

  1. C++智能指针(auto_ptr)详解

    智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...

  2. 自己动手实现智能指针auto_ptr

    面试的时候,我们经常会被问到如何自己动手实现智能指针auto_ptr.今天我就一边参考STL库中的源代码,一边将auto_ptr的实现敲一遍. auto_ptr归根到底是一个模版类,那么这个类要实现哪 ...

  3. C++ 智能指针auto_ptr

    template<class T> class auto_ptr { public: ); // Item M5 有“explicitfor”// 的描述 template<clas ...

  4. 关于智能指针auto_ptr

    智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...

  5. C++中的智能指针(auto_ptr)

    实际上auto_ptr 仅仅是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势.使用它不必每次都手动调用delete去释放内存.当然有利也有弊,也不是全然完美的. 本 ...

  6. 【C++】智能指针auto_ptr简单的实现

    //[C++]智能指针auto_ptr简单的实现 #include <iostream> using namespace std; template <class _Ty> c ...

  7. 智能指针auto_ptr & shared_ptr

    转载:智能指针auto_ptr 很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它.这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生 ...

  8. C++智能指针--auto_ptr指针

    auto_ptr是C++标准库提供的类模板,头文件<memory>,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同一时候被分给两个拥有者.当 ...

  9. 【C++智能指针 auto_ptr】

    <More Effective C++>ITEM M9他提到auto_ptr.说是当异常产生的时候.怎么释放为对象分配的堆内存,避免反复编写内存释放语句. PS:这里书里面提到函数退出问题 ...

随机推荐

  1. 375. Clone Binary Tree【LintCode java】

    Description For the given binary tree, return a deep copy of it. Example Given a binary tree: 1 / \ ...

  2. 《Git学习指南》学习笔记(一)

    第二章 入门 git的安装 在Linux下,git的安装很简单.以我的系统Deepin/Ubuntu为例,只需在终端敲入sudo apt-get install git即可.其他Linux发行版可尝试 ...

  3. LeetCode 104——二叉树中的最大深度

    1. 题目 2. 解答 如果根节点为空,直接返回 0.如果根节点非空,递归得到其左右子树的深度,树的深度就为左右子树深度的最大值加 1. /** * Definition for a binary t ...

  4. LeetCode - 463. Island Perimeter - O(MN)- (C++) - 解题报告

    原题 原题链接 You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 ...

  5. 声明变量&定义变量

            从编译原理上来说,声明是仅仅告诉编译器,有个某类型的变量会被使用,但是编译器并不会为它分配任何内存.而定义就是分配了内存.这对于以关键字extern进行声明是一定成立的,而对声明格式“ ...

  6. 欢迎来怼--第七次Scrum会议

    一.小组信息 队名:欢迎来怼 小组成员: 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华 小组照片 二.开会信息 时间:2017/10/19 17:05~17:17,总计12min. 地 ...

  7. 20172330 2017-2018-1 《Java程序设计》第三周学习总结

    20172330 2017-2018-1 <Java程序设计>第三周学习总结 教材学习内容总结 这一章的主要内容是关于类与对象,通过对String类,Random类,Math类等一系列道德 ...

  8. 二叉搜索树(BST)---python实现

    github:代码实现 本文算法均使用python3实现 1. 二叉搜索树定义   二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree).   二叉搜 ...

  9. LintCode-53.翻转字符串

    翻转字符串 给定一个字符串,逐个翻转字符串中的每个单词. 说明 单词的构成:无空格字母构成一个单词 输入字符串是否包括前导或者尾随空格?可以包括,但是反转后的字符不能包括 如何处理两个单词间的多个空格 ...

  10. 【week6】约跑App视频链接

    约跑视频链接发布在优酷,链接如下: http://v.youku.com/v_show/id_XMTc3NTcyNTcyNA==.html 秒拍视频连接: http://www.miaopai.com ...