【C++】智能指针的设计逻辑:RAII与资源安全

手动管理内存,本质是在跟"忘记释放"和"异常打断"两件事较劲。一段代码new了两块内存,中间某个函数调用抛了异常,后面的delete永远执行不到,泄漏就发生了。智能指针解决的就是这个场景------让资源有确定的、不依赖正常流程的释放时机。

目录

[1. 资源泄漏的典型场景](#1. 资源泄漏的典型场景)

[2. RAII:把资源绑在对象生命周期上](#2. RAII:把资源绑在对象生命周期上)


1. 资源泄漏的典型场景

下面这段代码很直观地展示了问题:Func里new了两个数组,然后调用Divide。如果除零抛异常,后面正常的delete不会被执行。即便用try/catch包住,如果在array2的new时也抛异常,那array1就已经泄漏了------catch里根本不知道array2有没有分配成功。

cpp

复制代码
void Func() {
    int* array1 = new int[10];
    int* array2 = new int[10];  // 这一行也可能抛异常

    try {
        int len, time;
        cin >> len >> time;
        cout << Divide(len, time) << endl;
    } catch (...) {
        delete[] array1;
        delete[] array2;
        throw;   // 清理后重新抛出
    }

    delete[] array1;
    delete[] array2;
}

手动一层层套try/catch来保释放,代码臃肿不说,逻辑一复杂就容易漏。这个问题不是"程序员不细心",而是一种结构性缺陷------资源释放依赖正常控制流走到,而异常偏偏打断了控制流。

2. RAII:把资源绑在对象生命周期上

RAII(Resource Acquisition Is Initialization)的思路很简单:在构造函数里获取资源,在析构函数里释放资源。对象在栈上分配,离开作用域时析构函数一定会被调用,不管你是正常return还是异常抛出去。这个"一定"是C++语言保证的,用户不用写哪怕一行try/catch来管释放。

cpp

复制代码
template<class T>
class SmartPtr {
public:
    SmartPtr(T* ptr) : _ptr(ptr) {}
    ~SmartPtr() {
        cout << "delete " << _ptr << endl;
        delete[] _ptr;
    }

    T& operator*()  { return *_ptr; }
    T* operator->() { return _ptr; }
    T& operator[](size_t i) { return _ptr[i]; }

private:
    T* _ptr;
};

用这个最简单的SmartPtr改造Func

cpp

复制代码
void Func() {
    SmartPtr<int> sp1(new int[10]);
    SmartPtr<int> sp2(new int[10]);

    for (size_t i = 0; i < 10; ++i)
        sp1[i] = sp2[i] = i;

    int len, time;
    cin >> len >> time;
    cout << Divide(len, time) << endl;
}
// 无论正常结束还是异常退出,sp1/sp2析构,资源释放

不需要try/catch了。Divide抛异常,栈展开析构sp2再析构sp1,两个数组被delete干净。代码量反而更少。这就是RAII对资源安全的根本价值------把不确定的手动释放变成确定的自动析构

智能指针本质上就是RAII在指针资源上的具体应用。除了自动释放,它还要解决另一个问题:如何像原生指针一样去访问资源?于是有了operator*operator->operator[]等运算符重载。这两点构成了智能指针的两个基本面:资源管理与指针模拟。

RAII并不只用于内存。文件句柄、网络连接、互斥锁,凡是"获取-使用-释放"的资源,都可以用同样的思路管理。等介绍shared_ptr配合自定义删除器时,会看到一个fopen的例子。

相关推荐
不会就选b18 分钟前
【无标题】
算法
LorryJovens21 分钟前
【LAAP论文】Chat GPT6来临:当一个强认知框架下的harness工程遇到强模型的安全对齐应对的调查研究
安全
m0_7393128733 分钟前
【自动驾驶和机器人控制】万向锁(Gimbal Lock)原理详解 + 和欧拉角 / 四元数 / SO(3)对比
算法·机器人·自动驾驶
见叶之秋43 分钟前
【C++】String类的使用(含模拟实现)
java·开发语言·c++
Felven1 小时前
A. Eating Game
算法
Flynt1 小时前
Chrome 修了个零日漏洞,你的 VS Code 和 Cursor 可能还在裸奔
安全·electron·visual studio code
wuminyu1 小时前
Linux内核线程调度与虚拟线程调度机制系统级深度剖析
java·linux·c语言·jvm·c++
TechWayfarer1 小时前
做IP归属地查询时总是查不准?IP纯净度检测实战:从“查归属地“到识别“脏IP“的四个维度
服务器·网络·python·tcp/ip·安全·web安全
huizhulihuiwu2 小时前
高端大型会议会务系统 私有化部署:如何平衡安全、性能与成本?
大数据·安全·会议签到·智能会议·会务系统
血小板要健康2 小时前
队列 + 宽搜(BFS):二叉树层序遍历 算法总结
java·数据结构·笔记·算法·leetcode·宽度优先