【C++ 】智能指针:内存管理的 “自动导航仪”

时间:2025-04-15 07:42:26

此小点内容来源于:豆包AI

#include <iostream>
#include <memory>

// 自定义类
class MyClass {
public:
    MyClass() { std::cout << "MyClass constructor" << std::endl; }
    ~MyClass() { std::cout << "MyClass destructor" << std::endl; }
    void doSomething() { std::cout << "Doing something..." << std::endl; }
};

class B;

class A {
public:
    std::shared_ptr<B> bPtr;
    ~A() { std::cout << "A destructor" << std::endl; }
};

class B {
public:
    std::weak_ptr<A> aPtr; // 使用 weak_ptr 避免循环引用
    ~B() { std::cout << "B destructor" << std::endl; }
};

void uniquePtrExample() {
    // 创建一个 unique_ptr 指向 MyClass 对象
    std::unique_ptr<MyClass> uniquePtr = std::make_unique<MyClass>();

    // 调用对象的成员函数
    uniquePtr->doSomething();

    // unique_ptr 不能被复制,但可以转移所有权
    // std::unique_ptr<MyClass> anotherPtr = uniquePtr; // 错误,不能复制
    std::unique_ptr<MyClass> anotherPtr = std::move(uniquePtr);

    if (!uniquePtr) {
        std::cout << "uniquePtr is empty after move" << std::endl;
    }

    if (anotherPtr) {
        anotherPtr->doSomething();
    }
}

void sharedPtrExample() {
    // 创建一个 shared_ptr 指向 MyClass 对象
    std::shared_ptr<MyClass> sharedPtr1 = std::make_shared<MyClass>();
    std::cout << "Shared pointer 1 use count: " << sharedPtr1.use_count() << std::endl;

    // 复制 shared_ptr,引用计数增加
    std::shared_ptr<MyClass> sharedPtr2 = sharedPtr1;
    std::cout << "Shared pointer 1 use count after copy: " << sharedPtr1.use_count() << std::endl;
    std::cout << "Shared pointer 2 use count: " << sharedPtr2.use_count() << std::endl;

    // 调用对象的成员函数
    sharedPtr2->doSomething();

    // 释放一个 shared_ptr,引用计数减少
    sharedPtr2.reset();
    std::cout << "Shared pointer 1 use count after reset sharedPtr2: " << sharedPtr1.use_count() << std::endl;
}

void weakPtrExample() {
    std::shared_ptr<A> a = std::make_shared<A>();
    std::shared_ptr<B> b = std::make_shared<B>();

    a->bPtr = b;
    b->aPtr = a;

    std::cout << "A use count: " << a.use_count() << std::endl;
    std::cout << "B use count: " << b.use_count() << std::endl;

    // 当 a 和 b 离开作用域时,对象会被正确销毁
}

int main() {
    std::cout << "=== Unique Ptr Example ===" << std::endl;
    uniquePtrExample();
    std::cout << std::endl;

    std::cout << "=== Shared Ptr Example ===" << std::endl;
    sharedPtrExample();
    std::cout << std::endl;

    std::cout << "=== Weak Ptr Example ===" << std::endl;
    weakPtrExample();
    std::cout << std::endl;

    return 0;
}    

在 C++ 里,手动管理动态分配的内存容易引发内存泄漏、悬空指针等问题。智能指针作为一种类模板,能有效管理动态分配的内存,避免这些问题的出现。C++ 标准库提供了三种主要的智能指针:std::unique_ptrstd::shared_ptr 和 std::weak_ptr

std::unique_ptr

std::unique_ptr 属于独占式智能指针,它对所指向的对象拥有唯一的所有权。一旦 std::unique_ptr 被销毁,其指向的对象也会随之被自动销毁。

 

在 uniquePtrExample 函数中:

 
  • 借助 std::make_unique 创建了一个 std::unique_ptr,它指向 MyClass 的一个对象。
  • 调用 doSomething 方法来使用这个对象。
  • 尝试复制 std::unique_ptr 会引发编译错误,因为它不允许复制,不过可以使用 std::move 转移所有权。
  • 转移所有权之后,原 std::unique_ptr 变为空。
std::shared_ptr

std::shared_ptr 是共享式智能指针,多个 std::shared_ptr 能够指向同一个对象。它采用引用计数来管理对象的生命周期,当引用计数变为 0 时,对象就会被销毁。

 

在 sharedPtrExample 函数中:

 
  • 利用 std::make_shared 创建了一个 std::shared_ptr,它指向 MyClass 的一个对象。
  • 通过 use_count 方法可以查看当前的引用计数。
  • 复制 std::shared_ptr 会使引用计数增加。
  • 调用 reset 方法可以释放 std::shared_ptr,从而使引用计数减少。
std::weak_ptr

std::weak_ptr 是弱引用智能指针,它不拥有对象的所有权,只是对 std::shared_ptr 所管理的对象进行弱引用。std::weak_ptr 主要用于解决 std::shared_ptr 的循环引用问题。

 

在 weakPtrExample 函数中:

 
  • 定义了 A 和 B 两个类,其中 A 类包含一个 std::shared_ptr<B> 成员,B 类包含一个 std::weak_ptr<A> 成员。
  • 创建了 A 和 B 的 std::shared_ptr 对象,并相互引用。
  • 由于 B 类使用了 std::weak_ptr,所以不会出现循环引用,当 a 和 b 离开作用域时,对象能够被正确销毁。