SmartPtr - 智能指针

前言

SmartPtr技术经常被人误解为是一种GC手段。理论上它可以成为GC,但这只能够是一种“理论”而已1

我个人倾向于把SmartPtr理解为一种异常处理规范(Exception Handling Specification)。与异常处理相关,程序设计有一个基本原则:无论发生何种异常,应尽可能保证申请的资源(包括但不限于内存资源)被释放。

在资源申请、释放在一个局部过程中时,可以采用的方式有:

try..catch

在申请一个资源那一刻开始,到资源释放的整个过程,使用try..catch将代码包含。以下是这个过程的标准写法:

MyClass* pObj = new MyClass; // 申请内存资源的开始
try
{
    ... // 对该内存资源的正常处理过程
}
catch(...)
{
    delete pObj;
    throw; // 将异常重新抛出
}
delete pObj;

使用资源句柄类

将资源用类进行包装,由类进行资源的申请、释放操作。这种类我们称为资源句柄类(Resource Handle Class)。在这种技术下,以上例子简化为很简单几句代码:

std::auto_ptr<MyClass> spObj(new MyClass);
... // 对该内存资源的正常处理过程

即使发生异常,C++编译器仍然可以保证,声明在栈中,并且已经被构造的自动变量在异常机制的“栈展开”过程中执行析构操作,从而保证了资源的释放。

释义

智能指针(SmartPtr)其实只是是资源句柄类(Resource Handle Class)中的一种。当一个资源句柄类管理的是内存资源时,我们称之为智能指针(SmartPtr)。

从实现上来说,多数智能指针是带引用计数(Reference Count)的,如:boost::shared_ptrATL::CComPtr等。当然也有简单不带计数的,如STL的std::auto_ptr

缺陷

我们推荐对所有的资源(而不单单是内存资源)使用资源句柄类。而相反,其实内存资源我们反倒不推荐使用资源句柄类。这句话的正确的理解是:

我们不推荐你用智能指针(SmartPtr),而是推荐用GC Allocator技术去解决内存管理问题。

因为内存资源的使用环境过于复杂,已经远超出了简单的资源句柄类可以解决的范畴。

实作

相关参考

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License