引言
在 C++ 的世界里,指针赋予了开发者直接操作内存的强大能力,但也埋下了内存泄漏、野指针、二次释放等一系列隐患。手动管理内存不仅繁琐,还容易因逻辑疏忽导致程序崩溃。幸运的是,C++11 标准库引入了智能指针,通过 RAII(资源获取即初始化)机制,将对象的生命周期与指针绑定,实现了内存的自动管理。
本文将深入解析 unique_ptr、shared_ptr 和 weak_ptr 的设计原理与实战技巧,帮助你彻底掌握现代 C++ 的内存管理模式。
一、裸指针的痛点
在使用智能指针之前,理解裸指针(Raw Pointer)的问题至关重要。
1. 内存泄漏
最常见的噩梦是忘记释放内存。例如在函数提前返回时,若未执行 delete,分配的堆内存将无法回收。
void func() {
int* p = new int(10);
if (some_condition) return; // 提前返回,p 未被释放
delete p;
}
2. 二次释放
对同一块内存多次调用 delete 会破坏堆结构,导致未定义行为或崩溃。
3. 野指针
指向已释放或非法地址的指针。例如返回局部变量的地址,函数结束后栈内存失效,指针即成野指针。
4. 异常安全
若代码抛出异常,正常的 delete 语句可能被跳过,造成资源泄漏。
二、智能指针的核心类型
C++11 提供了三种核心智能指针,分别对应不同的所有权模型。
1. unique_ptr:独占所有权的'独行侠'
unique_ptr 是最简单高效的智能指针,它拥有对象的唯一所有权,禁止拷贝,仅支持移动语义。
原理
底层封装裸指针,禁用拷贝构造函数,析构时自动调用 delete。其简化实现如下:
template <typename T>
class MyUniquePtr {
private:
T* ptr;
public:
explicit MyUniquePtr(T* p = nullptr) : ptr(p) {}
~MyUniquePtr() { delete ptr; }
// 禁用拷贝
( MyUniquePtr&) = ;
MyUniquePtr& =( MyUniquePtr&) = ;
(MyUniquePtr&& other) : (other.ptr) {
other.ptr = ;
}
};


