一、智能指针的场景需求
如果一个程序中手动 new 了对象,申请了空间资源,随后代码抛出了异常,就会导致申请的资源没有手动释放,造成内存泄漏。我们通常需要在 catch 语句里先 delete 资源。可是,new 本身也可能抛出异常,导致处理起来非常麻烦。
double divide(int a, int b) {
if (b == 0) {
throw std::string("Divide by zero condition!");
}
return (double)a / (double)b;
}
void Func() {
int* arr = new int[10];
try {
divide(1, 0);
} catch (const std::string& s) {
delete[] arr;
std::cout << s << std::endl;
}
}
智能指针在这样的场景下处理就十分轻松,无需手动干预异常路径下的资源释放。
二、智能指针的设计思路
RAII(Resource Acquisition Is Initialization)是一种管理资源的类设计思想,本质是利用对象生命周期来管理获取的动态资源,避免资源泄漏。这里的资源包括内存、文件指针、网络连接、互斥锁等。
RAII 在获取资源时把资源委托给一个对象,控制对资源的访问,资源在对象的生命周期内始终保持有效。在对象析构的同时释放资源,这样就保障了资源的正常释放,避免资源泄露。对象的生命周期结束后会自动调用析构函数,也就能使资源自动释放,无需我们再手动操作。
智能指针类除了满足上述 RAII 的思想,还需要方便资源的访问,所以一般还需要重载 operator*, operator->, operator[] 等运算符:
template <class T>
class SmartPtr {
public:
SmartPtr(T* ptr) : _ptr(ptr) {}
~() {
[] _ptr;
std::cout << << std::endl;
}
T& *() { *_ptr; }
T* ->() { _ptr; }
T& []( i) { _ptr[i]; }
:
T* _ptr;
};







