起: 

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. Spring中的Resource

    Spring中的资源定义:Resource此接口的全名为:org.springframework.core.io.Resource比较常用的资源定义的实现类为:1.ClassPathResource ...

  2. C#获取cpu序列号 硬盘ID 网卡硬地址以及操作注册表 .

    转:http://blog.csdn.net/smartsmile2012/article/details/8682295 #region 获取cpu序列号 硬盘ID 网卡硬地址 /**/ /// & ...

  3. python学习笔记八--动态类型

    一.变量,对象,引用: 1. 变量: 2. 对象:均包含了一个头部信息,有以下两部分内容 a.对象的数据类型, b.引用计数器:纪录当前引用货指向该对象的数量,一旦计数器被清零,该对象的内存空间就会被 ...

  4. Tiny4412汇编流水灯代码,Tiny4412裸机LED操作[1]

    从今天开始就正式进入到tiny4412的开发学习中了,今天主要看了一下Tiny4412的启动流程及存储器映射及Exynos4412数据手册,用汇编写了一个跑马灯程序(后续会有C语言版本的出来),先说一 ...

  5. Java多线程性能优化

    大家使用多线程无非是为了提高性能,但如果多线程使用不当,不但性能提升不明显,而且会使得资源消耗更大.下面列举一下可能会造成多线程性能问题的点: 死锁 过多串行化 过多锁竞争 切换上下文 内存同步 下面 ...

  6. UVa 11082 (网络流建模) Matrix Decompressing

    网络流不难写,难的建一个能解决问题的模型.. 即使我知道这是网络流专题的题目,也绝不会能想出这种解法,=_=|| 题意: 给出一个矩阵的 前i行和 以及 前i列和,然后找到一个满足要求的矩阵,而且每个 ...

  7. ShareSDK 实现新浪微博分享(微信,QQ,新浪微博类似)

    1 . 分享(前提是集成了sdk,配置好了Key),只要实现点击事件,调用shareSina(); ShareSDK.initSDK(this); private void shareSina() { ...

  8. js jquery版本的 金额千分位转换函数(非正则,效率极高)

    没想到js里面没有 金额千分位格式化的处理函数(例:1,234.01 这样的格式),网上搜了一圈,都是使用正则的方式处理的.正则的效率不敢恭维啊,又耗费资源速度又慢(虽然处理起来会直观一些). 因此专 ...

  9. jsp、js、html等

    1.一个button标签怎么触发事件: 一般触发事件有两种方式,要么是在html直接绑定,即button标签中不只有class.type和id,还要写onclick=... 还有一种,就是在js代码部 ...

  10. Parallel stepped for loops in .NET C# z

    ; i < ; i += ) public IEnumerable<int> SteppedIntegerList(int startIndex, int endEndex, int ...