起: 

C++98标准加入auto_ptr,即智能指针,C++11加入shared_ptr和weak_ptr两种智能指针,先从auto_ptr的定义学习一下auto_ptr的用法。

template<class _Ty>
class auto_ptr
{ // wrap an object pointer to ensure destruction
public:
//定义_Myt类型,作用域局限于类中,便于书写和理解
typedef auto_ptr<_Ty> _Myt;
typedef _Ty element_type;
//显式调用构造函数,对类型进行检查并构造一个_Ty类型的指针
//未定义默认构造函数 
explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()
: _Myptr(_Ptr)
{ // construct from object pointer
}
//定义了复制构造函数,稍微有些奇特的复制构造函数,构造了this以后,_Right就会变成一个_Myt类型的NULL指针,这点须谨记,具体参见release的定义。
//上面即所有权转移,同一个指针在多个auto_ptr对象之间只会存在一份所有权,可以避免析构的重复delete错误。
auto_ptr(_Myt& _Right) _THROW0()
: _Myptr(_Right.release())
{ // construct by assuming pointer from _Right auto_ptr
}
//通过auto_ptr_ref结构体来构造智能指针,所有权转移
auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()
{ // construct by assuming pointer from _Right auto_ptr_ref
_Ty *_Ptr = _Right._Ref;
_Right._Ref = 0; // 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 = 0; // pass ownership to auto_ptr_ref
return (_Ans);
}
//赋值操作符=的重载函数之一:独占新指针的所有权并delete当前拥有的指针
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
}
//赋值操作符=的重载之一:独占新指针的所有权并delete当前拥有的指针
_Myt& operator=(_Myt& _Right) _THROW0()
{ // assign compatible _Right (assume pointer)
reset(_Right.release());
return (*this);
}
//赋值操作符=的重载之一:独占新指针的所有权并delete当前拥有的指针
_Myt& operator=(auto_ptr_ref<_Ty> _Right) _THROW0()
{ // assign compatible _Right._Ref (assume pointer)
_Ty *_Ptr = _Right._Ref;
_Right._Ref = 0; // release old
reset(_Ptr); // set new
return (*this);
}
//析构删除当前指向的资源,用的delete而非delete [],所以只能用来删除单个抽象数据对象,不能删除数组,需要关注,指向的对象应该是用new构造出来的,而不是new []构造的。
~auto_ptr() _NOEXCEPT
{ // destroy the object
delete _Myptr;
}
//重载*操作符,返回指向的对象
_Ty& operator*() const _THROW0()
{ // return designated value
 #if _ITERATOR_DEBUG_LEVEL == 2
if (_Myptr == 0)
_DEBUG_ERROR("auto_ptr not dereferencable");
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
return (*get());
}
//重载操作符->,内部调用get()方法
_Ty *operator->() const _THROW0()
{ // return pointer to class object
 #if _ITERATOR_DEBUG_LEVEL == 2
if (_Myptr == 0)
_DEBUG_ERROR("auto_ptr not dereferencable");
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
return (get());
}
//返回指向资源的指针
_Ty *get() const _THROW0()
{ // return wrapped pointer
return (_Myptr);
}
//将this指针指向NULL,并返回指向资源的指针
_Ty *release() _THROW0()
{ // return wrapped pointer and give up ownership
_Ty *_Tmp = _Myptr;
_Myptr = 0;
return (_Tmp);
}
//delete已拥有的指针并获取新的指针所有权,reset使用时候要注意这一点
void reset(_Ty *_Ptr = 0)
{ // destroy designated object and store new pointer
if (_Ptr != _Myptr)
delete _Myptr;
_Myptr = _Ptr;
}
private:
_Ty *_Myptr; // the wrapped object pointer
};
学习小结:
1. 每一个auto_ptr都是一个ADT对象,auto_ptr应当被定义成局部或临时变量,以便自动析构拥有的指针。
2. auto_ptr中很重要的一个理念就是所有权转移,所有权转移就是auto_ptr会接管赋给他们的指针的所有权,以后这个指针有且仅有一个auto_ptr拥有。复制构造和赋值操作都会接管指针的所有权。
3. 从整个设计理念看,get()和release()提供了某些灵活性的同时破坏了概念的一致性,使用不当会导致某些错误,所有权不再由唯一的auto_ptr具有,要少用这两个接口。
4. auto_ptr适用于管理new出来的指针,不适用new[]出来的指针,也不要用auto_ptr指向静态分配对象的指针。
5. auto_ptr不满足STL容器的基本要求,因为auto_ptr的复制操作是所有权的转移,而不是所有权的拷贝,不要试图用容器来容纳auto_ptr,也不适用sort等内部会对元素进行拷贝的函数。
6. auto_ptr提供的接口列表:显式构造函数、复制构造函数的各个重载版本、赋值操作符的各个重载版本、操作符*、操作符->、release()、get()、reset()。

 后记:

学习boost,认为boost中的一种与auto_ptr极其类似的智能指针scoped_ptr的设计是不错的,auto_ptr的所有权可以转移,同一时间只有一个auto_ptr可以管理指针,但还是具有一定的危险性,而scoped_ptr把拷贝构造函数和赋值函数全都私有化,保证了指针的绝对安全,从概念上保持了完整性,大多数时候是一种更好的选择。

【C++深入浅出】智能指针之auto_ptr学习的更多相关文章

  1. [3] 智能指针std::auto_ptr

    [1]std::auto_ptr 对于编译器来说,智能指针实质是一个栈对象,而并非指针类型. 智能指针通过构造函数获取堆内存的管理所有权,而在其生命期结束时,再通过析构函数释放由它所管理的堆内存. 所 ...

  2. 智能指针之 auto_ptr

    C++的auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理,该智能指针在C++11中已经被弃用,转而由unique_ptr替代, 那这次使用和实现,就具体讲一下auto_pt ...

  3. 智能指针之auto_ptr和scoped_ptr

    部分参考地址https://blog.csdn.net/yanglingwell/article/details/56011576 auto_ptr是c++标准库里的智能指针,但是具有以下几个明显的缺 ...

  4. C++ 智能指针 std::auto_ptr 分析

    背景介绍: RAll机制 定义一个类来封装资源的分配和释放,在构造函数中完成资源的分配和初始化,在析构函数中完成资源的清理,从而保证资源的正确初始化和清理 ps:智能指针就是RAll机制的一种应用,智 ...

  5. 智能指针shared_ptr使用学习

    当需要shared_ptr实现向上向下转换时,可以使用 dynamic_pointer_cast 来进行转换 下面是例子: #include <memory> using namespac ...

  6. 智能指针shared_ptr, auto_ptr, scoped_ptr, weak_ptr总结

    看这里: http://blog.csdn.net/lollipop_jin/article/details/8499530 shared_ptr可以多线程同时读,但是涉及到写,需要加锁. share ...

  7. auto_ptr,shared_ptr 智能指针的使用

    Q: 那个auto_ptr是什么东东啊?为什么没有auto_array?A: 哦,auto_ptr是一个很简单的资源封装类,是在<memory>头文件中定义的.它使用“资源分配即初始化”技 ...

  8. 深入学习c++--智能指针(一) shared_ptr

    1. 几种智能指针 1. auto_ptr: c++11中推荐不使用他 2. shared_ptr: 每添加一次引用 就+1,减少一次引用,就-1:做到指针进行共享 3. unique_ptr: 一个 ...

  9. C++ 智能指针Auto_PTR 分析

    C++的动态内存的分配与释放是个挺折磨人的事情,尤其异常分支复杂时(比如一堆try catch中,各catch里需要做delete 掉相关的堆上分配的内存),极有可能产生内存泄露的情况.C++中提供了 ...

随机推荐

  1. Android 九宫格密码锁进入程序

    设置九宫格密码锁进入程序,设置,重置,取消等,安卓巴士地址http://www.apkbus.com/forum.php?mod=viewthread&tid=182620&extra ...

  2. Nginx+uWSGI或fastcgi部署Django项目

    nginx+uWSGI ubuntu下先安装下C编译器和Python环境: sudo apt-get install build-essential python-dev 使用pip安装uWSGI: ...

  3. 【原创】通俗易懂的讲解KMP算法(字符串匹配算法)及代码实现

    一.本文简介 本文的目的是简单明了的讲解KMP算法的思想及实现过程. 网上的文章的确有些杂乱,有的过浅,有的太深,希望本文对初学者是非常友好的. 其实KMP算法有一些改良版,这些是在理解KMP核心思想 ...

  4. jquery 图片无缝切换

    想要和园友分享一下学习jquery的经验.总结,更希望园友提出点建议. 第一次写,有不好的地方请多多见谅! 文笔有限,很多时候不知道怎么来描述,唉.硬伤啊!!那只好多做了,贴代码... ok,废话少说 ...

  5. net remoting 服务器端订阅客户端(附源代码)

    remoting 在分布式应用中逐渐在企业级应用发展开来,最初提出分布式应用,主要目的是为了降低服务器的压力,将耗性能的处理放在另外一个程序中,然后将计算结果发送到另外一个应用中.而remoting就 ...

  6. DataView.RowFilter筛选DataTable中的数据

    //定义一个DataView ,得到一个全部职员的视图DataView dataView1 = DbHelperSQL.QueryDataView(sql); //过滤得到一个只显示男职员的视图 da ...

  7. HDU 4571 Travel in time ★(2013 ACM/ICPC长沙邀请赛)

    [题意]给定N个点,每个点有一个停留所需的时间Ci,和停留能够获得的满意度Si,有M条边,每条边代表着两个点走动所需的时间ti,现在问在规定的T时间内从指定的一点S到E能够获得的最大的满意度是多少?要 ...

  8. WEB架构师成长之路-架构师都要懂哪些知识 转

    Web架构师究竟都要学些什么?具备哪些能力呢?先网上查查架构师的大概的定义,参见架构师修炼之道这篇文章,写的还不错,再查查公司招聘Web架构师的要求. 总结起来大概有下面几点技能要求: 一. 架构师有 ...

  9. 新功能:Azure Traffic Manager 嵌套配置文件

    Jonathan Tuliani  Azure 网络 - DNS 和 Traffic Manager 项目经理 我们很高兴地宣布,Azure Traffic Manager 支持 Traffic Ma ...

  10. Java [leetcode 29]Divide Two Integers

    题目描述: Divide two integers without using multiplication, division and mod operator. If it is overflow ...