auto_ptr的VC版本源码剖析
auto_ptr是当前C++标准库(STL)中提供的一种智能指针,包含于头文件 #include<memory> 。auto_ptr 能够方便的管理单个堆内存对象,在你不用的时候自动帮你释放内存。
一个版本的auto_ptr是Linux和VS中使用的,另一个是VC版本的,下面是VC版本的auto_ptr的源代码剖析:
1 template<class _Ty> 2 class auto_ptr 3 { 4 public: 5 explicit auto_ptr(_Ty *_P=0):_Owns(_P!=0),_Ptr(_P) //构造 6 {} 7 8 ~auto_ptr() //析构 9 { 10 if (_Owns) //当拥有权限为真,delete指针所指向的内容 11 { 12 delete _Ptr; 13 } 14 } 15 16 auto_ptr(const auto_ptr<_Ty> &_Y):_Owns(_Y._Owns),_Ptr(_Y.release()) //拷贝构造 17 {} 18 19 auto_ptr<_Ty>& operator=(const auto_ptr<_Ty> &_Y) //拷贝赋值 20 { 21 //若pa2=pa1 22 if (this!=&_Y) //当两个对象不是自身复制 23 { 24 if (_Ptr!=_Y._Ptr) // 当pa2和pa1指向地址不同 25 { 26 if (_Owns) //pa2有指向,就析构pa2指向的内容 27 { 28 delete _Ptr; 29 } 30 _Owns = _Y._Owns; //将pa1的拥有权限转移到pa2 31 } 32 else if(_Y._Owns) //如果pa1和pa2指向地址相同,判断pa1是否有拥有权 33 { 34 _Owns = true; //如果pa1有拥有权,则pa2赋值为有拥有权 35 } 36 _Ptr = _Y.release(); //将pa1拥有权释放,并将pa1指针赋值给pa2 37 } 38 return *this; // 返回pa2 39 } 40 41 42 _Ty& operator*() const //重载* 43 { 44 return *_Ptr; 45 } 46 47 _Ty* operator->() const //重载-> 48 { 49 return _Ptr; 50 } 51 52 _Ty* release() const //将拥有权限释放,并返回指针 //常对象只能调用常方法所以要加const 53 { 54 ((auto_ptr<_Ty>*) this)->_Owns = false; //将拥有权限释放 //强制转换是为了让const失去作用,就是将const auto_ptr类型强转为auto_ptr类型,就可以修改_Y了,但出了这一步,_Y还是const的,_Y.Owns=0;就会报错 55 return _Ptr; 56 } 57 58 private: 59 bool _Owns; //加了mutable关键字,此变量就不受const的限制,但是不安全 60 _Ty *_Ptr; 61 };
当pa2 = pa1时 :
1.pa2 无指向 : 将pa1的指针给pa2赋值,再将pa1将拥有权进行转移;
2.pa2 有指向不同于pa1的对象 : 将pa2的指向进行析构,再将pa1的指针给pa2赋值,将pa1的拥有权转移;
3.pa2 有指向和pa1相同的对象 : 判断pa1是否有拥有权,有则将pa1的拥有权转移给pa2。
但vc版的auot_ptr也有一些问题,就是将拥有权转移后,除了不能够对其多次析构外,还可以对其进行操作,这就不好了,你都已经分手了,还不放手。在VS版本上对拥有权有更好的管理。
如果两个指针指向一个空间但是都没有拥有权,最后需要用delete释放。