一、RALL机制
RAII(Resource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术。
他的思想是资源分配即初始化,定义一个类来封装资源的的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确释放和初始化
RAII要求,资源的有效期与持有资源的对象的⽣命期严格绑定,即由对象的构造函数完成资源的分配(获取),同时由析构函数完成资源的释放。在这种要求下,只要对象能正确地析构,就不会出现资源泄露问题。
二、基于RALL思想提出的智能指针
智能指针就是基于RAII的要求使用模板类,自动化地管理动态资源的释放(不管理资源的创建),智能指针看上去是指针,实际上是赋予了定义的对象。智能指针(smart pointer)是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动态分配的资源,防止内存泄露。
(1)auto_ptr:独占所有权,所有权转移
为实现auto_ptr我们需要实现该类的构造、拷贝构造、赋值运算符重载、operator*、operator->等成员函数,重载*和->是为了可以使只能指针像原生指针一样访问。
问:在auto_ptr类中如何解决拷贝构造中的浅拷贝引起的析构多次的问题呢?
auto_ptr版本的智能指针采用的是管理权转移的方法,即由a构造出b对象之后,a对象置为NULL,即a对象不再管理该空间,只有b一个对象维护该空间。
缺点:不能真正实现拷贝构造和赋值运算符重载的目的
模拟实现auto_ptr
#include<iostream>
using namespace std;
template<typename T>
class Auto_ptr
{
public:
Auto_ptr(T* ptr=NULL)
:_ptr(ptr)
{
cout<<"构造"<<endl;
}
//管理权转移
Auto_ptr(Auto_ptr<T>& ap)
{
cout<<"拷贝构造"<<endl;
_ptr=ap._ptr;
ap._ptr=NULL;//ap的_ptr已经失效;
}
//管理权转移
Auto_ptr<T>& operator=(Auto_ptr<T>& ap)
{
cout<<"赋值运算符重载"<<endl;
if (this!=&ap)
{
delete _ptr;
_ptr=ap._ptr;
ap._ptr=NULL;//ap的_ptr已经失效;
}
return *this;
}
~Auto_ptr()
{
if (_ptr!=NULL)
{
cout<<"析构"<<endl;
delete _ptr;
_ptr=NULL;
}
}
//像原生指针一样访问对象
T& operator*()
{
return *_ptr;
}
//方便对自定义对象的成员进行访问
T* operator->()
{
return _ptr;
}
p