智能指针——使用与实现
Effective C++的条款13:以对象管理资源 智能指针就是一种用类模拟普通指针,实现以对象管理资源的方法。
先看一下智能指针的用法:
#include <iostream> #include <memory> // 有auto_ptr这个类模板 using namespace std; int main() { auto_ptr<int> p(new int(100)); // p是个对象,但重载了*运算符,行为与指针完全一样 cout << *p << endl; // 100 return 0; }
auto_ptr就是我们的智能指针,是一个模版,构造方法参数是普通的指针。智能指针的使用几乎方法完全一样。
C++提供了几种智能指针auto_ptr、unique_ptr、shared_ptr和weak_ptr。各种指针的基本思想大致相同,都是通过在栈上定义一个指向对象的指针来控制对象,所以智能指针的生命周期结束时会自动调用对象的析构函数。
下面是auto_ptr的源码,事实上auto_ptr已经被弃用了,但由于其比较简单而且各种智能指针比较接近,所以用auto_ptr作为例子。
#include <iostream> using namespace std; template<class _Ty>
class auto_ptr { public: typedef _Ty element_type; explicit auto_ptr(_Ty *_P = 0) _THROW0() : _Owns(_P != 0), _Ptr(_P) {} auto_ptr(const auto_ptr<_Ty>& _Y) _THROW0() : _Owns(_Y._Owns), _Ptr(_Y.release()) {} auto_ptr<_Ty>& operator=(const auto_ptr<_Ty>& _Y) _THROW0() {if (this != &_Y) {if (_Ptr != _Y.get()) {if (_Owns) delete _Ptr; _Owns = _Y._Owns; } else if (_Y._Owns) _Owns = true; _Ptr = _Y.release(); } return (*this); } ~auto_ptr() {if (_Owns) delete _Ptr; } _Ty& operator*() const _THROW0() {return (*get()); } _Ty *operator->() const _THROW0() {return (get()); } _Ty *get() const _THROW0() {return (_Ptr); } _Ty *release() const _THROW0() {((auto_ptr<_Ty> *)this)->_Owns = false; return (_Ptr); } private: bool _Owns; _Ty *_Ptr; };
可以看出,使用auto_ptr,同一个资源只会有一个指向它的指针。
auto_ptr<Object> ptr1 (new Object()); auto_ptr<Object> ptr2 (ptr1); //ptr2指向对象,ptr1=null ptr1 = ptr2; //ptr1指向对象,ptr2=null
这是auto_ptr与shared_ptr的主要不同,shared_ptr是引用计数型智能指针,它会追踪有多少对象指向资源,只有无人指向它时才自动释放资源。
shared_ptr<Object> ptr1 (new Object()); shared_ptr<Object> ptr2 (ptr1); //ptr1,ptr2指向对象 ptr1 = ptr2; //同上