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. 【WXS】简要介绍说明

    WXS(WeiXin Script)是小程序的一套脚本语言. WXS有二种写法: 1) 以<wxs>标签书写脚本: 语法: <wxs module="[String]&qu ...

  2. Centos7下部署activeMQ消息队列服务

    #1.下载activeMQlinux包 http://activemq.apache.org/activemq-5100-release.html   下载linux的activeMQ包 #2.使用X ...

  3. I Hate It:线段树:单点修改+区间查询

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. CryptoZombies学习笔记——Lesson1

    CryptoZombies是一个学习以太坊开发的平台,我将在这里记录学习过程中的一些笔记. 课程网址:cryptozombies.io 首先是第一课——Lesson1:Making the Zombi ...

  5. SpringCloud IDEA 教学 (五) 断路器控制台(HystrixDashboard)

    写在开头 断路器控制台是为了查看断路器运行情况而研发的.本章介绍了断路器控制台的搭建,代码基于之前Client的搭建.HystrixDashboard基于之前配置好的,使用了HystrixComman ...

  6. A Compatible Pair

    Description “年”是一个生活在海洋深处的怪物.每年,它都出现在陆地上,吞噬牲畜甚至是人.为了让怪物离开,人们用红色,光线和爆炸的声音填满他们的村庄,所有这些都吓跑了怪物.   小汤米有 n ...

  7. lintcode-189-丢失的第一个正整数

    189-丢失的第一个正整数 给出一个无序的正数数组,找出其中没有出现的最小正整数. 样例 如果给出 [1,2,0], return 3 如果给出 [3,4,-1,1], return 2 挑战 只允许 ...

  8. lintcode-160-寻找旋转排序数组中的最小值 II

    160-寻找旋转排序数组中的最小值 II 假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2). 你需要找到其中最小的元素. 数组中可能存在 ...

  9. epoll&ext4文件系统

    1.第一个终端运行nesttest,nesttest首先fork一个子进程,然后父进程退出,子进程首先打开一个txt普通文件对应fd为3,然后创建一个epfd,对应fd为4 lybxin@Inspir ...

  10. pfx 证书怎么打开

    其实双击就能够自动运行导入向导的 不行的话使用我的办法: 单击开始--运行--里输入mmc 然后单击文件--选择添加删除管理单元--再选择添加--拉动滚动条找到证书一项,点击添加再点击完成(不用做任何 ...