C++学习系列(15):C++ 智能指针(智能内存管理)
1. 引言
在 C++ 早期,手动管理动态内存(new/delete)是一项复杂且容易出错的工作,内存泄漏 是 C++ 开发者最常见的问题之一。
为了解决这个问题,C++11 引入了 智能指针(Smart Pointer),它们可以 自动管理动态分配的对象,避免手动 delete。
本篇博客将介绍:
- 为什么需要智能指针
- 三种智能指针
unique_ptr、shared_ptr、weak_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 期完结!🎉 感谢大家的支持!🚀
💡 如果你喜欢这篇文章,欢迎点赞、收藏,并关注本系列!
11万+

被折叠的 条评论
为什么被折叠?



