【C++深入浅出】智能指针之auto_ptr学习

起: 

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学习,布布扣,bubuko.com

时间: 2024-11-14 12:30:47

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

(转)剖析C++标准库智能指针(std::auto_ptr)

不可否认,资源泄露(resource leak)曾经是C++程序的一大噩梦.垃圾回收 机制(Garbage Collection)一时颇受注目.然而垃圾自动回收机制并不能 满足内存管理的即时性和可视性,往往使高傲的程序设计者感到不自在. 况且,C++实现没有引入这种机制.在探索中,C++程序员创造了锋利的 "Smart Pointer".一定程度上,解决了资源泄露问题. 也许,经常的,你会写这样的代码: //x拟为class: // class x{ // public: // int

智能指针 std::auto_ptr 和 shared_ptr

需要注意: auto_ptr 类可以用于管理由 new 分配的单个对象,但是无法管理动态分配的数组(我们通常不会使用数组,而是使用 vector 代替数组).auto_ptr 在拷贝和赋值的时候有不寻常的行为,因此 auto_ptrs 不能被保存在 stl 的容器中.当 auto_ptr 离开了自己的作用域或者被销毁,由 auto_ptr 管理的对象也会被销毁. 使用std::auto_ptr需要的头文件: #include <memory> // 示例 1(b): 安全代码, 使用了auto

四种智能指针:auto_ptr,unique_ptr,shared_ptr,weak_ptr

stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针的使用总结 (1)auto_ptr 主要用于解决资源自动释放的问题.防止用户忘记delete掉new申请的内存空间.使用auto_ptr会在离开变量的作用域之后直接调用析构函数进行资源释放. void Function() { auto_ptr<Obj> ptr(new Obj(20)); ... if (error occur) throw exception... } 但是,这是一种被c++1

C++智能指针之auto_ptr

1. auto_ptr auto_ptr 是C++标准库提供的类模板,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个拥有者.当auto_ptr对象生命周期结束时,其析构函数会将auto_ptr对象拥有的动态内存自动释放.即使发生异常,通过异常的栈展开过程也能将动态内存释放.auto_ptr不支持new 数组. 2. auto_ptr需要包含的头文件 #include <memory> 3. 初始化auto_ptr对象的方法 1) 构造

智能指针之 auto_ptr

C++的auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理,该智能指针在C++11中已经被弃用,转而由unique_ptr替代, 那这次使用和实现,就具体讲一下auto_ptr被弃用的原因,(编译平台:Linux centos 7.0 编译器:gcc 4.8.5 ) 首先使用std::auto_ptr时,需要#include <memory>头文件,具体使用代码如下(文件名:test_ptr.cpp): #include <memory> #include

智能指针之auto_ptr和scoped_ptr

部分参考地址https://blog.csdn.net/yanglingwell/article/details/56011576 auto_ptr是c++标准库里的智能指针,但是具有以下几个明显的缺陷,使用时要注意 1.就是所谓的控制权转移,下面是模拟代码 auto_Ptr(auto_Ptr<T>&ap) { _ptr = new T; //先分配空间 _ptr = ap._ptr; //再资源转移 ap._ptr = NULL; //将原来的指针置空 } 在赋值运算符重载和拷贝构造

智能指针(auto_ptr)vc版

auto_ptr包含于头文件 #include<memory> 其中<vector><string>这些库中也存有.auto_ptr 能够方便的管理单个堆内存对象,在你不用的时候自动帮你释放内存. auto_ptr的设计目的: 局部对象获取的资源(内存),当函数退出时,它们的析构函数被调用,从而自动释放这些资源,但是,如果以显式手法获得的资源(称为动态分配内存空间如:new.malloc等)没有绑定在任何对象身上,必须以显式手法释放.(如:delete,free等).

auto_ptr,shared_ptr 智能指针的使用

Q: 那个auto_ptr是什么东东啊?为什么没有auto_array?A: 哦,auto_ptr是一个很简单的资源封装类,是在<memory>头文件中定义的.它使用“资源分配即初始化”技术来保证资源在发生异常时也能被安全释放(“exception safety”).一个auto_ptr封装了一个指针,也可以被当作指针来使用.当其生命周期到了尽头,auto_ptr会自动释放指针.例如: #include<memory> using namespace std;  struct X

智能指针的模拟实现 auto_ptr scoped_ptr shared_ptr

RAII(Resource Acquisition Is Initialization) 资源分配即初始化,定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放. 智能指针:用自动化或者说智能的指针来实现对动态内存的释放.它是一个类,有类似指针的功能. 常见的智能指针:auto_ptr/scoped_ptr/scoped_array/shared_ptr/shared_array,由于scoped_array和scoped_