智能指针概述

智能指针是C++标准库提供的模板类,用于自动管理动态内存,避免内存泄漏和悬空指针问题。它们通过RAII(资源获取即初始化)机制,在对象生命周期结束时自动释放内存。


常用智能指针类型

shared_ptr(共享指针)
  • 特点:通过引用计数管理内存,多个shared_ptr可指向同一对象,计数为0时自动释放内存。
  • 用法示例
    #include <memory>
    std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
    std::shared_ptr<int> ptr2 = ptr1; // 引用计数+1
    

  • 注意:循环引用会导致内存泄漏(需结合weak_ptr解决)。
unique_ptr(独占指针)
  • 特点:独占所有权,不可复制,但可通过移动语义转移所有权。
  • 用法示例
    std::unique_ptr<int> ptr = std::make_unique<int>(100);
    std::unique_ptr<int> ptr2 = std::move(ptr); // 所有权转移
    

  • 优势:零运行时开销,适合替代裸指针。
weak_ptr(弱指针)
  • 特点:配合shared_ptr使用,不增加引用计数,解决循环引用问题。
  • 用法示例
    std::shared_ptr<int> sptr = std::make_shared<int>(200);
    std::weak_ptr<int> wptr = sptr;
    if (auto tmp = wptr.lock()) { // 检查对象是否存活
        // 使用tmp(shared_ptr)
    }
    


智能指针的核心操作

创建与初始化
  • 优先使用std::make_sharedstd::make_unique(C++14起),避免显式new
    auto ptr = std::make_shared<std::string>("Hello");
    

自定义删除器
  • 可为智能指针指定自定义释放逻辑(如文件句柄、网络连接):
    std::unique_ptr<FILE, decltype(&fclose)> filePtr(fopen("test.txt", "r"), fclose);
    

资源释放
  • 显式释放资源并重置指针:
    ptr.reset(); // 释放内存,ptr置空
    


使用场景与陷阱

适用场景
  • 动态数组管理(unique_ptr支持数组):
    std::unique_ptr<int[]> arr(new int[10]);
    

  • 多线程共享数据(shared_ptr需确保原子操作)。
常见陷阱
  • 避免混用裸指针和智能指针:
    int* raw = new int(5);
    std::shared_ptr<int> ptr(raw); // 错误:可能多次delete
    

  • 禁止返回thisshared_ptr(需继承enable_shared_from_this)。

性能与最佳实践

  • 性能unique_ptr接近裸指针,shared_ptr有计数开销。
  • 实践建议
    • 默认使用unique_ptr,仅在需要共享时用shared_ptr
    • 使用weak_ptr打破循环引用。
    • 避免在接口中传递智能指针(除非明确所有权语义)。

通过合理使用智能指针,可显著提升C++代码的安全性和可维护性。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐