智能指针是一种在编程中管理动态内存资源的对象。它封装了原始指针(raw pointer),并提供额外的功能,例如自动释放资源、避免内存泄漏和管理对象的生命周期。智能指针广泛用于需要动态分配内存的语言(如 C++),通过 RAII(Resource Acquisition Is Initialization)原则实现内存管理。

在 C++ 中,智能指针主要在 <memory> 头文件中定义,包括以下几种类型:


1. std::unique_ptr

  • 特点

    • 独占所有权(一个对象只能有一个 unique_ptr 拥有它)。
    • 不可复制,但可以通过 std::move 转移所有权。
    • 适合需要明确单一所有权的场景。
  • 用法

    1
    2
    3
    4
    5
    6
    7
    8
    #include <memory>
    #include <iostream>

    int main() {
    std::unique_ptr<int> ptr = std::make_unique<int>(42); // 创建智能指针
    std::cout << *ptr << std::endl; // 输出 42
    return 0; // 离开作用域时,自动释放资源
    }

2. std::shared_ptr

  • 特点

    • 共享所有权(多个智能指针可以共享同一个资源)。
    • 通过引用计数管理资源生命周期,计数归零时释放资源。
    • 使用场景:多个对象需要共享同一资源。
  • 用法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <memory>
    #include <iostream>

    int main() {
    std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
    std::shared_ptr<int> ptr2 = ptr1; // 共享同一资源
    std::cout << *ptr1 << ", " << *ptr2 << std::endl; // 输出 42, 42
    return 0; // 所有 `shared_ptr` 离开作用域时释放资源
    }

3. std::weak_ptr

  • 特点

    • shared_ptr 配合使用,弱引用(不增加引用计数)。
    • 用于解决循环引用问题(两个对象通过 shared_ptr 相互引用,导致资源无法释放)。
    • 在访问资源前需要检查是否有效。
  • 用法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <memory>
    #include <iostream>

    int main() {
    std::shared_ptr<int> shared = std::make_shared<int>(42);
    std::weak_ptr<int> weak = shared; // 创建弱引用

    if (auto locked = weak.lock()) { // 检查资源是否有效
    std::cout << *locked << std::endl; // 输出 42
    }
    return 0; // 资源离开作用域时自动释放
    }

优点

  1. 避免内存泄漏:智能指针会自动释放资源,无需手动调用 delete
  2. 安全性:通过封装原始指针,减少指针操作中的错误(如悬空指针、重复释放)。
  3. 易于使用:支持语义清晰的接口和自动管理生命周期。

缺点

  1. 引入了额外的内存开销(如 shared_ptr 的引用计数)。
  2. 需要注意循环引用问题(可通过 weak_ptr 避免)。
  3. 不适用于所有场景,例如实时性能要求特别高的代码。

智能指针 vs 原始指针

特性 智能指针 原始指针
内存管理 自动释放 手动释放
安全性 更安全(防止悬空指针等问题) 容易出错
使用复杂度 较低 较高
性能 略有开销(如引用计数) 无开销

智能指针在现代 C++ 中被广泛使用,是 C++11 引入的重要功能之一,极大地提高了代码的安全性和可维护性。