智能指針就是智能/自動化的管理指針所指向的動態資源的釋放。並且可以向指針一樣使用。
1、早期auto_ptr—是一種失敗的設計,有設計缺陷
爲了解決對象中指針的重複釋放,採用管理權轉移的方式。
即在解決對象的賦值、拷貝構造時,比如:a = b;將a的地址空間釋放,然後將b.ptr的指針賦給a.ptr,最後將地址空間的管理權交付於a.ptr,並將b.ptr致null。因此,在賦值過後,將不能使用原來指針,缺點就是不能有幾個指針指向同一塊內存,一個智能指針只能指向一塊內存。
下面我們可以模擬auto_ptr
#include <iostream>
using namespace std;
template <typename T>
class AutoPtr
{
public:
AutoPtr(T* ptr = NULL)
:_ptr(ptr)
{}
AutoPtr(AutoPtr<T>& ap)
:_ptr(ap._ptr)
{
delete ap->_ptr;
}
AutoPtr<T>& operator=(AutoPtr<T>& ap)
{
if (this != &ap)
{
delete _ptr;
this->_ptr = ap._ptr;
ap._ptr = NULL;
}
return *this;
}
T& operator*()const
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
~AutoPtr()
{
if (NULL != _ptr)
{
delete _ptr;
_ptr = NULL;
}
}
private:
T* _ptr;
};
class AA
{
public:
int a;
int b;
};
void funtest1()
{
AutoPtr<AA> ap1(new AA);
(*ap1).a = 10;
(*ap1).b = 20;
ap1->a = 30;
ap1->b = 40;
}
void funtest2()
{
AutoPtr<int> ap3(new int[10]);
AutoPtr<int> ap4(new int[5]);
ap3 = ap4;
}
int main()
{
funtest2();
system("pause");
return 0;
}
2.發展期:在使用時期,開發者逐漸發現auto_ptr的不足,於是有一些開發者逐漸放棄auto_ptr並且自主實現auto_ptr功能,例如scoped_ptr/share_ptr/week_ptr
1 scoped_ptr在實現智能指針時採用簡單粗暴的方式,採用仿函數,在外部不允許使用,不允許進行拷貝構造函數和賦值運算符重載。
scoped的模擬實現:
template<class T>
class ScopedPtr
{
public:
ScopedPtr(T* ptr = NULL)
:_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>&);
protected:
T* _ptr;
};
share_ptr採用引用技術思想,在對象構造時記下使用次數,到最後只有一個使用結束時再釋放。並且支持拷貝構造和賦值運算符重載。
share_ptr模擬:
template<typename T>
class Shared_Ptr
{
public:
Shared_Ptr(T* ptr)
:_ptr(ptr)
,_count(new int(0))
{
}
~Shared_Ptr()
{
if(
{
delete _ptr;
delete _count;
_ptr=_count=NULL;
}
}
Shared_Ptr(Shared_Ptr<T> & a)
{
_ptr=a._ptr;
_count=a._count;
(*_count)++;
}
Shared_Ptr<T>& operator =(Shared_Ptr<T>& a)
{
if(&a!=this)
{
if(
{
delete _ptr;
delete _count;
_ptr=_count=NULL;
}
_ptr=a._ptr;
_count=a._count;
(*_count)++;
}
return *this;
}
Shared_Ptr<T>& operator =(Shared_Ptr<T> a)
{
if(a!=&this)
{
swap(a._ptr,_ptr);
swap(a._count,_count);
}
return *this;
}
T* operator ->()
{
return _ptr;
}
T& operator *()
{
return *_ptr;
}
protected:
T* _ptr;
int * _count;
};
在C++11中才加入了shared_ptr和unique_ptr,weak_ptr。