- 概念
- 發展歷史
- 第一階段(C++98):auto_ptr ----自動指針
- 第二階段(C++03):即在Boost中的智能指針
- 第三階段(C++11):
- AutoPtr
template<class T>
class AutoPtr
{
public:
AutoPtr(T* ptr)
:_ptr(ptr)
{}
~AutoPtr()
{
cout<<"指針被釋放"<<endl;
if(_ptr)
{
delete _ptr;
}
}
//運算符的重載(像指針一樣)
T& operator* ()
{
return *_ptr;//*(this->_ptr)
}
T* operator->()
{
return _ptr;
}
//拷貝構造
AutoPtr(AutoPtr<T>& ap)//管理權轉移
:_ptr(ap._ptr)
{
ap._ptr = NULL;
}
//ap1=ap2
AutoPtr<T>& operator=(AutoPtr<T> &ap)
{
if(this != &ap)
{
if(_ptr)
delete _ptr;
_ptr = ap._ptr;
ap._ptr = NULL;
}
return *this;
}
private:
T* _ptr;
};
分析:這裏是因爲 ap2 完全的奪取了 ap1 的管理權。然後導致訪問 ap1 的時候程序就會崩潰。如果在這裏調用 ap2 = ap1 程序一樣會崩潰,原因還是 ap1 被奪走管理權,所以這種編程思想及其不符合C++思想,所以它的設計思想就是有一定的缺陷。因此,一般不推薦使用 auto_ptr 智能指針。
- ScopedPtr
template<class T> class ScopedPtr { public: ScopedPtr(T* ptr) :_ptr(ptr) {} ~ScopedPtr() { if(_ptr) { delete _ptr; } } T& operator*() { return *_ptr; } T* operator->() { return _ptr; } private: ScopedPtr(const ScopedPtr<T> &sp);//不能定義爲公有的,防止在類外實現 ScopedPtr<T>& operator=(const ScopedPtr<T> &sp); private: T *_ptr; };
- SharedPtr
template<class T>
class SharedPtr
{
friend class WeakPtr<T>;
public:
SharedPtr(T* ptr)
:_ptr(ptr)
,_refcount(new int(1))
{}
~SharedPtr()//當引用技術爲0時,釋放空間
{
cout<<"~SharedPtr()"<<endl;
if(--(*_refcount)==0)
{
printf("ox%p\n",_ptr);
delete _ptr;
delete _refcount;
}
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
//sp2(sp1)
SharedPtr(const SharedPtr<T>& sp)
:_ptr(sp._ptr)
,_refcount(sp._refcount)
{
(*_refcount)++;
}
//sp1 = sp2
SharedPtr<T> &operator = (const SharedPtr<T>& sp)
{
if(_ptr != sp._ptr) //防止自已給自已賦值
{
if(--(*_refcount)==0)
{
delete _ptr;
delete _refcount;
}
_ptr = sp._ptr;
_refcount = sp._refcount ;
(*_refcount)++;
}
return *this;
}
private:
T* _ptr;
int* _refcount;//引用次數
};
struct ListNode
{
int _data;
ListNode* _next;
ListNode* _prev;
~ListNode()
{
cout<<"ListNode"<<endl;
}
};
void TestRec()
{
ListNode* cur = new ListNode;
ListNode* next = new ListNode;
cur->_next = next;
next->_prev = cur;
delete cur;
delete next;
}
(2)含有智能指針的雙向鏈表
struct ListNode
{
int _data;
SharedPtr<ListNode> _next;
SharedPtr<ListNode> _prev;
ListNode()
:_data(0)
,_next(NULL)
,_prev(NULL)
{}
~ListNode()
{
cout<<"ListNode"<<endl;
}
};
void TestRec()
{
SharedPtr<ListNode> cur(new ListNode);
SharedPtr<ListNode> next(new ListNode);
cur->_next = next; //加上這兩句導致循環引用
next->_prev = cur;
}
- WeakPtr
template <class T>
class WeakPtr
{
public:
WeakPtr()
:_ptr(NULL)
{}
WeakPtr(const SharedPtr<T> & sp)
:_ptr(sp._ptr)
{}
WeakPtr<T>& operator=(const SharedPtr<T>& sp)
{
_ptr = sp._ptr;
return *this;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
private:
T* _ptr;
};
struct ListNode
{
int _data;
WeakPtr <ListNode> _next;
WeakPtr <ListNode> _prev;
ListNode()
:_data(0)
,_next(NULL)
,_prev(NULL)
{}
~ListNode()
{
cout<<"~ListNode"<<endl;
}
};
void TestRec()
{
SharedPtr<ListNode> cur(new ListNode);
SharedPtr<ListNode> next(new ListNode);
cur->_next = next;
next->_prev = cur;
}