C++ RAII 与智能指针:面试必备知识点 1 什么是RAIIRAIIResource Acquisition Is Initialization资源获取即初始化是 C 中一种重要的资源管理技术。其核心思想是将资源的生命周期与对象的生命周期绑定。在对象构造时获取资源在对象析构时释放资源。这里的“资源”包括堆内存、文件句柄、互斥锁、网络连接、数据库会话等任何需要手动释放的东西RAII 的好处自动释放无论函数正常返回还是抛出异常局部对象的析构函数都会被调用资源一定会被释放。异常安全避免因异常导致的资源泄漏。代码简洁无需到处写free、close、unlock等清理代码。2 智能指针RAII 在内存管理上的体现C11 提供了三种智能指针它们都是 RAII 思想的直接应用——将动态分配的堆内存交给栈上的对象管理当智能指针对象离开作用域时自动释放所管理的堆内存。2.1 unique_ptr —— 独占所有权同一时刻只有一个unique_ptr指向一块内存禁止拷贝允许移动move大小与裸指针开销相同零开销最适合工厂函数的返回值、类成员变量等场景std::unique_ptrint p1(new int(42)); // std::unique_ptrint p2 p1; // 编译错误禁止拷贝 std::unique_ptrint p2 std::move(p1); // 移动后 p1 变为 nullptr // 工厂函数 std::unique_ptrWidget createWidget() { return std::make_uniqueWidget(); }2.2 shared_ptr —— 共享所有权多个shared_ptr可以指向同一对象通过引用计数管理生命周期。当最后一个shared_ptr被销毁时自动释放对象。内部有控制块包含引用计数和自定义 deleter 等信息。推荐使用std::make_shared创建更安全、性能更好。auto sp1 std::make_sharedint(10); auto sp2 sp1; // 引用计数变为 2 sp1.reset(); // 引用计数减为 1对象仍存活 sp2.reset(); // 引用计数归零对象被释放注意shared_ptr的引用计数是线程安全的原子操作但所管理的对象本身不是线程安全的需要额外同步2.3 weak_ptr —— 弱引用解决循环引用不增加引用计数只观察shared_ptr管理的对象。通过lock()方法获取临时的shared_ptr如果对象已释放则返回空主要用途打破shared_ptr的循环引用例如双向链表、父子节点struct Node { std::shared_ptrNode next; std::weak_ptrNode prev; // 使用 weak_ptr 避免循环引用 }; auto a std::make_sharedNode(); auto b std::make_sharedNode(); a-next b; b-prev a; // 不会增加 a 的引用计数3 RAII 与智能指针的关系概念RAII智能指针本质一种编程思想RAII 在内存管理上的具体实现管理对象任意资源内存、锁、文件等堆内存动态分配的对象实现方式构造获取、析构释放构造函数接管内存析构函数调用 delete典型例子LockGuard、ifstreamunique_ptr、shared_ptr、weak_ptr可以说智能指针是 RAII 思想最成功的应用之一。它们将“手动管理堆内存”的痛苦降到最低让开发者专注于业务逻辑4 面试常见问题速记RAII 的核心是什么​资源获取即初始化将资源生命周期绑定到对象生命周期。为什么智能指针能避免内存泄漏​因为智能指针是栈上对象离开作用域自动调用析构函数在析构中释放堆内存。unique_ptr和shared_ptr如何选择​优先用unique_ptr除非确实需要共享所有权。unique_ptr零开销语义清晰。make_shared相比直接new有什么好处​1)异常安全避免new和构造智能指针之间的间隙2)一次堆分配对象和控制块合并性能更好weak_ptr的作用是什么​打破循环引用观察对象是否存活不延长生命周期。