C++学习系列(15):C++ 智能指针(智能内存管理)

C++学习系列(15):C++ 智能指针(智能内存管理)

1. 引言

在 C++ 早期,手动管理动态内存new/delete)是一项复杂且容易出错的工作,内存泄漏 是 C++ 开发者最常见的问题之一。

为了解决这个问题,C++11 引入了 智能指针(Smart Pointer),它们可以 自动管理动态分配的对象,避免手动 delete

本篇博客将介绍:

  • 为什么需要智能指针
  • 三种智能指针 unique_ptrshared_ptrweak_ptr
  • 智能指针的使用场景
  • 智能指针的最佳实践

2. 为什么需要智能指针?

2.1 传统 new/delete 的问题

#include <iostream>

void foo() {
    int* p = new int(10);  // 动态分配内存
    std::cout << *p << std::endl;
    // ❌ 这里忘记 delete,导致内存泄漏!
}

📌 问题

  • 忘记 delete 导致内存泄漏
  • 可能出现 悬垂指针(指向已经释放的内存)
  • 异常安全问题(抛异常时,可能不会执行 delete

智能指针 解决这些问题,自动管理内存。


3. unique_ptr(独占所有权)

3.1 unique_ptr 基本用法

#include <iostream>
#include <memory>  // 包含智能指针头文件

int main() {
    std::unique_ptr<int> ptr = std::make_unique<int>(10); // 自动管理内存
    std::cout << *ptr << std::endl;
    return 0; // 作用域结束时,自动释放内存
}

unique_ptr 独占资源,不可复制,生命周期结束时自动释放内存


3.2 unique_ptr 不能被复制

std::unique_ptr<int> p1 = std::make_unique<int>(10);
std::unique_ptr<int> p2 = p1;  // ❌ 编译错误

unique_ptr 不能拷贝,但可以 std::move() 转移所有权

std::unique_ptr<int> p1 = std::make_unique<int>(10);
std::unique_ptr<int> p2 = std::move(p1);  // ✅ 允许

4. shared_ptr(共享所有权)

shared_ptr 允许多个指针共享同一个对象,使用引用计数管理资源

4.1 shared_ptr 基本用法

#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> sp1 = std::make_shared<int>(20); // 创建智能指针
    std::shared_ptr<int> sp2 = sp1;  // 共享所有权

    std::cout << "引用计数:" << sp1.use_count() << std::endl; // 输出 2

    return 0; // 作用域结束,计数变为 0,自动释放
}

shared_ptr 采用 引用计数,当 use_count() == 0 时释放资源


4.2 shared_ptr 自动管理动态数组

std::shared_ptr<int[]> arr(new int[5]);  // ✅ 可以管理数组

5. weak_ptr(弱引用)

weak_ptr 不会增加引用计数,用于解决 shared_ptr 循环引用 问题。

5.1 weak_ptr 解决循环引用

#include <iostream>
#include <memory>

struct B;
struct A {
    std::shared_ptr<B> bptr;
    ~A() { std::cout << "A 被销毁\n"; }
};

struct B {
    std::weak_ptr<A> aptr;  // ✅ 避免循环引用
    ~B() { std::cout << "B 被销毁\n"; }
};

int main() {
    std::shared_ptr<A> a = std::make_shared<A>();
    std::shared_ptr<B> b = std::make_shared<B>();

    a->bptr = b;
    b->aptr = a;  // ✅ 使用 weak_ptr,避免循环引用

    return 0;  // 作用域结束时,A 和 B 正确销毁
}

使用 weak_ptr 解决 shared_ptr 循环引用问题


6. 智能指针最佳实践

指针类型用途
unique_ptr独占资源,适用于 局部对象
shared_ptr共享资源,适用于 多个对象共享资源
weak_ptr避免 shared_ptr 循环引用

📌 建议

  • 优先使用 unique_ptr(性能最佳)
  • 如果需要共享资源,使用 shared_ptr
  • 避免循环引用时,使用 weak_ptr

7. 总结

unique_ptr 独占所有权,生命周期结束自动释放
shared_ptr 引用计数管理,适用于多个对象共享资源
weak_ptr 不增加引用计数,避免 shared_ptr 循环引用
智能指针帮助 C++ 进行安全、高效的内存管理


📢 至此,C++学习系列全部 15 期完结!🎉 感谢大家的支持!🚀

💡 如果你喜欢这篇文章,欢迎点赞、收藏,并关注本系列!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值