智能指針,顧名思義它是一個聰明的指針,那麼到底聰明到哪了呢,讓咱們一塊兒來看如下的代碼。ide
void test1() //內存泄露 { int *p = new int(1); if (1) { //... return; } //... //... delete p; }
智能指針就是能夠自動化地管理指針所指向的動態內存的釋放。this
STL---AutoPtr (管理權轉移,不推薦使用)包含在頭文件 #include<memory>中。spa
新方案:(管理權轉移),std::auto_ptr 可以方便的管理單個堆內存對象。指針
template<class T> class AutoPtr //管理權轉移 { public: AutoPtr(T *ptr) :_ptr(ptr) {} ~AutoPtr() { if (_ptr == NULL) { cout << "delete:" << _ptr << endl; delete _ptr; } } AutoPtr(AutoPtr<T> &ap) :_ptr(ap._ptr) { ap._ptr = NULL; //管理權轉移 } AutoPtr<T>& operator=(AutoPtr<T> & ap) { if (this != &ap) { delete _ptr; _ptr = ap._ptr; ap._ptr = NULL; } return *this; } T &operator*() { return *_ptr; } T *operator->() { return _ptr; } protected: T *_ptr; };
舊方案:(在某些狀況下,會產生野指針)xml
思路:在新方案的基礎上,新增一個bool變量(_owner),只要_owner爲true,才析構,再也不經過將賦值的值置空。對象
template<class T> class AutoPtr { public: AutoPtr(T *ptr) :_ptr(ptr) , _owner(true) {} ~AutoPtr() { if (_owner == true) { delete _ptr; } } AutoPtr( AutoPtr<T>& ap) :_ptr(ap._ptr) , _owner(ap._owner) { ap._owner = false; } AutoPtr<T>& operator=(AutoPtr<T>& ap) { if (this != &ap) { delete _ptr; _ptr = ap._ptr; _owner = ap._owner; ap._owner = false; } return *this; } protected: T *_ptr; bool _owner; }; void test1() { AutoPtr<int> ap1(new int(1)); AutoPtr<int> ap2(ap1); AutoPtr<int> ap3(new int(2)); ap3 = ap2; }
2. boost—ScopedPtr(防拷貝。簡單、粗暴,只定義,不實現)內存
template<class T> class ScopedPtr //必須須要的1.聲明,2.保護類型 { public: ScopedPtr(T *ptr) :_ptr(ptr) {} ~ScopedPtr() { if (_ptr == NULL) { delete _ptr; } } T & operator*() { return *_ptr; } T* operator->() { return _ptr; } protected: //protected:防止別人搞破壞行爲 ScopedPtr( ScopedPtr<T> &sp); ScopedPtr<T>& operator=(ScopedPtr<T> &sp); protected: T *_ptr; };
3. boost—SharedPtr(引用計數的方法實現)ci
template<class T> class SharedPtr //引用計數 { public: SharedPtr(T *ptr) :_ptr(ptr) , _pcount(new int(1)) {} ~SharedPtr() { if (--(*_pcount)==0) { delete _ptr; delete _pcount; } } SharedPtr(const SharedPtr<T> &sp) :_ptr(sp._ptr) , _pcount(sp._pcount) { ++(*_pcount); } SharedPtr<T>& operator=(const SharedPtr<T>& sp) { if (_ptr != sp._ptr) //防止自賦值和同時管理同一塊空間 { if (--(*_pcount) == 0) { delete _ptr; delete _pcount; } _ptr = sp._ptr; _pcount = sp._pcount; ++(*_pcount); } return *this; } T& operator*() { return *_ptr; } T* operator->() { return _ptr; } protected: T *_ptr; int *_pcount; };