SuperAPI AI 工具集

cpp-smart-pointers

编程与开发

查看项目

更新于 10-16 02:09

技能介绍

用途

cpp-smart-pointers 面向在 C++ 中进行安全内存管理的场景,围绕智能指针(unique_ptr、shared_ptr、weak_ptr)与 RAII(Resource Acquisition Is Initialization,资源获取即初始化)模式展开,目标是实现自动、异常安全的资源管理。

主要能力

RAII 原则

资料将 RAII 描述为 C++ 的基本惯用法:资源生命周期绑定到对象生命周期。反例是手动 fopen/fclose,若中途抛异常则文件永不关闭;改进方式是用 unique_ptr 加自定义删除器,或封装一个 RAII 类(构造时获取资源、析构时释放,禁用拷贝、允许移动)。RAII 带来的好处包括异常安全(如 lock_guard 锁与 unique_ptr 内存同时自动释放)以及所有代码路径上的自动清理。

unique_ptr

提供对动态分配对象的独占所有权。推荐使用 std::make_unique 创建(C++14)。它是只可移动、不可拷贝的:通过 std::move 转移所有权,可作为函数参数接收所有权,也可作为返回值转移所有权。支持自定义删除器(函数指针、lambda、仿函数),资料给出 FILE* 与 socket 的删除器示例。常用操作包括解引用、get() 取裸指针、判断是否持有对象、release() 释放所有权、reset() 重置、swap() 交换。

shared_ptr

提供共享所有权与自动引用计数。资料建议优先使用 std::make_shared 而非 new,原因是 make_shared 只做一次分配(对象与控制块合并),而 new 方式需要两次分配,并且 make_shared 在异常安全上更稳妥。常用操作包括解引用、get()、use_count()、unique()、reset()、swap() 等。还介绍了别名构造函数(aliasing constructor),可生成指向成员但仍共享整个对象所有权的 shared_ptr。数组支持方面,资料指出 std::shared_ptr<int[]> 在 C++17 及以后可能因实现而异,make_shared 的数组支持在 C++20 加入。

weak_ptr

提供对 shared_ptr 所管理对象的非拥有引用,不增加引用计数。通过 expired() 判断对象是否已销毁,通过 lock() 获取可安全使用的 shared_ptr。资料用它解决循环引用导致的内存泄漏(双向链表中一侧改用 weak_ptr),并给出观察者模式与缓存模式(unordered_map 存 weak_ptr,命中时 lock,过期则清理)的示例。

自定义删除器与分配器

资料展示了多种删除器模式:日志删除器、数组删除器(delete[])、条件删除器、资源池删除器(归还而非删除)。自定义分配器方面,给出 TrackingAllocator 与 std::allocate_shared 配合使用的示例。

智能指针转换

安全转换包括:unique_ptr 转 shared_ptr(转移所有权)、shared_ptr 转 weak_ptr、weak_ptr 经 lock() 转 shared_ptr。向下转型提供 static_pointer_cast、dynamic_pointer_cast(失败返回 nullptr)、const_pointer_cast。资料同时提示裸指针直接构造 shared_ptr 存在风险。

性能考量

资料给出尺寸对比:裸指针与 unique_ptr 均为 8 字节(64 位),shared_ptr 与 weak_ptr 为 16 字节;shared_ptr 的控制块通常约 24–32 字节。优化建议包括:尽可能优先使用 unique_ptr,仅在需要时转为 shared_ptr;以 const 引用传递 shared_ptr 避免增加引用计数;用 weak_ptr 保存非拥有引用。

异常安全

资料以持有两个 unique_ptr 成员的类为例,说明如何先创建新资源、再提交更改,从而提供强异常保证(提交操作应为 noexcept)。

使用方式

该技能以代码示例为主体,覆盖创建、所有权转移、访问、重置、转换、删除器与分配器等操作方式,可作为编写现代 C++ 内存管理代码时的参考。具体安装或调用命令暂未提供。

适用场景

适用于需要在 C++ 中管理动态内存、文件句柄、socket 等资源的开发场景,尤其是要求异常安全、避免内存泄漏、处理共享所有权或循环引用的代码。

限制

资料未提供该技能的具体运行环境、依赖版本、安装步骤或收费信息。示例中涉及的 Resource、ResourcePool、load_resource、create_socket 等类型与函数未给出完整定义。数组支持等特性受 C++ 标准版本与实现影响,资料中已作提示。