c++中的智能指针主要是基于RAII思想的。
不懂RAII思想的同学可以看看这篇博文-->RAII思想---利用对象生命周期来控制程序资源
智能指针的两大要素
- RAII思想:把资源交给这个对象管理
- 像指针一样的行为(重载operator
*
和operator->
)
template<class T>
class SmartPtr
{
public://交给对象去管理
SmartPtr(T* ptr=nullptr)
:_ptr(ptr)
{}
~SmartPtr()
{
if (_ptr)
delete[] _ptr;
}
//像指针一样的行为
T& operator*()//对象出了作用域还在,所以返回引用
{
return *_ptr;
}
T* operator->()
{
return _ptr;//返回原生指针
}
private:
T* _ptr;
};
std::auto_ptr(C++98)
C++98版本的库中提供了auto_ptr的智能指针。
想要实现一个智能指针就要实现这几个功能:RAII思想,像指针一样的行为。但是对象会有拷贝构造和赋值,auto_ptr的原理是进行了管理权的转移(管理权的转移是当把a的值给b之后,就把a置成空),这是一种带有缺陷的智能指针,会导致对象悬空。
实现的原理如下:
template<class T>
class auto_ptr
{
public:
auto_ptr(T* ptr)
:_ptr(ptr)
{}
~auto_ptr()
{
if (_ptr != nullptr)
{
cout << "delete:" << _ptr << endl;
delete _ptr;
}
}
//拷贝构造ap1(ap2)---ap2拷贝构造ap1,此时把ap2置空,管理权交给ap1
//this指针是ap1,ap是ap2
auto_ptr(auto_ptr<T>& ap)
:_ptr(ap._ptr)
{
ap._ptr = nullptr;//不执行此句会崩溃,同一资源释放了两次
}
//赋值 ap1=ap2
auto_ptr<T>& operator=(auto_ptr<T>& ap)
{
if (this != &ap)//检测是否给自己赋值
{
//释放当前对象ap的资源
if (_ptr)
delete _ptr;
//转移ap中的资源到当前对象去
_ptr = ap._ptr;
ap._ptr = NULL;
}
return *this;//支持连续赋值
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
private:
T* _ptr;
};
auto_ptr是一种管理权转移的思想,由于转移之后原来的对象会被置空,会导致对象的悬空,如下:
void test_auto_ptr()
{
cpp::auto_ptr<int> ap1(new int);
cpp::auto_ptr<int> ap2(ap1);
// *ap1 = 10;//拷贝构造后管理权转移,ap1悬空
*ap2 = 20;
cpp::auto_ptr<int> ap3(new int);
//ap3 = ap2;//赋值把p2置空了
*ap3 = 40;
}
这里导致原来的对象悬空了,auto_ptr是带有缺陷的早期设计,因此很多公司都会禁用这个a