智能指针就是智能/自动化的管理指针所指向的动态资源的释放。并且可以向指针一样使用。
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。