举个例子,当我们动态申请一块内存空间,使用完毕之后也正常释放该内存空间,但是若是在申请与释放中间,我们进行了异常处理,程序直接结束,则将造成内存泄漏。
因此,我们引入智能指针。将自己申请的内存空间交给智能指针去处理。
RAII(不能等同于智能指针)资源分配及初始化( Resource Acquisition Is Initialization)
定义一个类来封装资源的分配和释放
一种规范,一种解决问题的思想,利用构造函数初始化、析构函数释放资源。
智能指针是RAII的一种应用,智能管理对象的释放问题,能够像指针一样使用(重载)。
在C++98/03中,终有auto_ptr
最终在C++11中,有了unique_ptr、shared_ptr、weak_ptr这三种智能指针,因此现如今共四种智能指针。
不过在C++11出现之前,就有了一个第三方库(boost)存在,它里面包含scoped_ptr、shared_ptr、weak_ptr,C++11也是在此基础上出现的。
(1)auto_ptr–>管理权转移
这是一种带有缺陷的设计,不建议使用。
(2)scoped_ptr–>防拷贝
简单粗暴的设计,无需考虑拷贝/赋值,使用智能指针时尽量使用这一种。
(3)shared_ptr–>引用计数管理
支持拷贝/赋值,但是也存在缺陷,会导致循环引用的问题。
(4)weak_ptr–>配合shared_ptr使用,解决循环引用问题
下面我们来看一下auto_ptr
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
template<typename T>
class AutoPtr
{
public:
AutoPtr(T* ptr = 0)
:_ptr(ptr)
{}
AutoPtr(AutoPtr<T>& ap)
:_ptr(ap._ptr)
{
ap._ptr = NULL;
}
AutoPtr<T>& operator=(AutoPtr<T>& ap)
{
if (this != &ap)
{
if (_ptr)
{
delete _ptr;
}
_ptr = ap._ptr;
ap._ptr = NULL;
}
return *this;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
~AutoPtr()
{
if (_ptr)
{
delete _ptr;
_ptr = NULL;
}
}
protected:
T* _ptr;
};
void FunTest()
{
AutoPtr<int> ap(new int(1));
AutoPtr<int> ap1(new int(2));
AutoPtr<int> ap2(ap);
AutoPtr<int> ap3;
ap3 = ap1;
*ap3 = 10;
*ap = 20;
}
int main()
{
FunTest();
return 0;
}
当解引用ap时,就会发生错误,这是因为现在ap已经是空的了,不能向里面写入内容。