实现简化版unique_ptr需遵循RAII原则,通过构造获取资源、析构释放资源,禁止拷贝、支持移动语义,确保独占所有权,利用操作符重载提供指针行为,自动管理内存防止泄漏。

实现一个简单的智能指针,尤其是模仿 unique_ptr,是理解 C++ 中 RAII(Resource Acquisition Is Initialization)机制的绝佳方式。RAII 的核心思想是:资源的生命周期由对象的生命周期自动管理——构造时获取资源,析构时释放资源。
下面通过手写一个简化版的 unique_ptr 来说明其原理和实现方式。
1. 简化版 unique_ptr 的基本结构
我们希望这个智能指针:
- 独占所管理的对象,不能被复制。
- 可以移动(move),转移所有权。
- 在析构时自动 delete 所指对象。
- 支持解引用和成员访问操作符。
template
public: // 构造函数:接收裸指针 explicit UniquePtr(T* p = nullptr) : ptr_(p) {}
// 析构函数:释放资源,体现 RAII
~UniquePtr() {
delete ptr_;
}
// 禁止拷贝构造和拷贝赋值
UniquePtr(const UniquePtr&) = delete;
UniquePtr& operator=(const UniquePtr&) = delete;
// 移动构造
UniquePtr(UniquePtr&& other) noexcept : ptr_(other.ptr_) {
other.ptr_ = nullptr; // 转移所有权
}
// 移动赋值
UniquePtr& operator=(UniquePtr&& other) noexcept {
if (this != &other) {
delete ptr_; // 释放当前资源
ptr_ = other.ptr_; // 接收所有权
other.ptr_ = nullptr;
}
return *this;
}
// 解引用
T& operator*() const {
return *ptr_;
}
// 成员访问
T* operator->() const {
return ptr_;
}
// 获取原始指针(不转移)
T* get() const {
return ptr_;
}
// 释放所有权,返回原始指针
T* release() {
T* temp = ptr_;
ptr_ = nullptr;
return temp;
}
// 重置内部指针
void reset(T* p = nullptr) {
delete ptr_;
ptr_ = p;
}};
立即学习“C++免费学习笔记(深入)”;
2. 使用示例
测试我们实现的 UniquePtr:
include
struct MyClass { int value; MyClass(int v) : value(v) { std::cout << "MyClass(" << value << ") constructed\n"; } ~MyClass() { std::cout << "MyClass(" << value << ") destructed\n"; } };
int main() {
{
UniquePtr
// ptr2 = ptr; // 编译错误:禁止拷贝
UniquePtrzuojiankuohaophpcnMyClassyoujiankuohaophpcn ptr2 = std::move(ptr); // 合法:移动
// 此时 ptr 为空,ptr2 拥有对象
} // 自动调用析构,释放资源
return 0;}
输出会显示构造和析构过程,证明资源被正确管理。
3. RAII 的体现
RAII 的关键在于“资源即对象”:
我们的 UniquePtr 把动态内存包装成一个局部对象,无需手动调用 delete,极大降低出错概率。
4. 关键点总结
- 独占语义:通过删除拷贝操作,保证同一时间只有一个智能指针拥有资源。
- 移动语义:使用右值引用实现安全的所有权转移。
- 自动清理:析构函数中 delete 是 RAII 的核心。
- 操作符重载:让智能指针像普通指针一样使用。
基本上就这些。实现一个简易 unique_ptr 不复杂但容易忽略细节,比如移动赋值中的自赋值检查和资源释放顺序。掌握它有助于深入理解现代 C++ 的资源管理哲学。











