理解 C++ 智能指针:原理、实现与最佳实践
智能指针概述智能指针本质上是封装了裸指针的类通过 RAII资源获取即初始化管理资源生命周期。常见智能指针std::unique_ptr独占所有权不能复制只能移动。std::shared_ptr共享所有权引用计数管理。std::weak_ptr弱引用不增加引用计数用于解决循环引用。三、std::unique_ptr3.1 基本用法代码语言javascriptAI代码解释cpp复制编辑std::unique_ptrint p1(new int(10)); // p1 拥有指针3.2 独占所有权代码语言javascriptAI代码解释cpp复制编辑std::unique_ptrint p2 std::move(p1); // p1 失效p2 拥有所有权3.3 自动释放机制智能指针析构时调用delete释放内存避免泄漏。3.4 自定义删除器代码语言javascriptAI代码解释cpp复制编辑std::unique_ptrFILE, decltype(fclose) fp(fopen(file.txt, r), fclose);支持管理非new分配资源。四、std::shared_ptr4.1 引用计数机制shared_ptr内部维护两个计数强引用计数当前持有所有权的shared_ptr数量弱引用计数weak_ptr数量计数为零时释放资源。4.2 典型用法代码语言javascriptAI代码解释cpp复制编辑std::shared_ptrint sp1 std::make_sharedint(20); std::shared_ptrint sp2 sp1; // 引用计数 14.3 控制块Control Block实际实现中资源指针和引用计数放在控制块里实现高效管理。4.4 循环引用问题若两个对象互相持有shared_ptr会导致内存泄漏。五、std::weak_ptr5.1 弱引用weak_ptr不拥有对象所有权不影响引用计数。5.2 解决循环引用代码语言javascriptAI代码解释cpp复制编辑struct B; struct A { std::shared_ptrB b_ptr; }; struct B { std::weak_ptrA a_ptr; // 弱引用避免循环 };5.3 lock() 获取shared_ptr通过lock()检查资源是否还存活。六、智能指针的内部实现原理6.1 Control Block 结构持有资源指针强引用计数弱引用计数删除器指针自定义删除器6.2 引用计数操作线程安全的计数增加和减少通常使用原子操作。七、最佳实践7.1 优先使用make_shared和make_uniquemake_shared在一块内存中分配对象和控制块提高性能。避免裸new。7.2 使用unique_ptr表达独占语义避免无谓的引用计数开销。7.3 注意循环引用用weak_ptr打破循环。7.4 自定义删除器管理非内存资源管理文件、socket 等资源。八、性能考量shared_ptr的引用计数增加和减少有一定开销。unique_ptr开销最小。不恰当的过度共享会导致性能下降。九、总结智能指针是现代 C 内存管理的基石理解其内部机制和使用规范对于写出安全、高效代码至关重要。通过合理选择智能指针类型并遵守最佳实践能够显著减少内存相关错误提升代码质量。