独占指针(unique_ptr)是C++11标准引入的一种智能指针,用于独占管理动态分配对象的生命周期。unique_ptr确保对象在同一时间只有一个所有者,防止对象被多个指针共享。下面是unique_ptr的实现原理及其内存管理机制。
unique_ptr 的基本原理
 
-  独占所有权: - unique_ptr独占对象的所有权,不能被复制,但可以移动。
- 通过移动语义,可以将所有权从一个 unique_ptr转移到另一个。
 
-  自动内存管理: - 当 unique_ptr被销毁时,它所管理的对象也会被销毁,自动释放内存。
 
- 当 
实现原理
-  基本结构: - unique_ptr是一个模板类,包含一个原始指针和一个删除器。
- 删除器是一个可调用对象(如函数指针、函数对象或 std::default_delete),用于在unique_ptr销毁时释放对象。
 
-  构造与析构: - 构造函数:接受一个原始指针,默认使用 std::default_delete作为删除器。
- 析构函数:调用删除器释放对象。
 
- 构造函数:接受一个原始指针,默认使用 
-  禁止复制: - unique_ptr禁止复制构造和复制赋值操作。
- 通过删除复制构造函数和复制赋值操作符来实现。
 
-  移动语义: - 允许移动构造和移动赋值操作。
- 通过移动构造和移动赋值操作符将所有权转移到另一个 unique_ptr。
 
代码示例
#include <iostream>
#include <memory>class MyClass {
public:MyClass() { std::cout << "MyClass constructed\n"; }~MyClass() { std::cout << "MyClass destroyed\n"; }void sayHello() { std::cout << "Hello\n"; }
};int main() {std::unique_ptr<MyClass> ptr1(new MyClass());ptr1->sayHello();// std::unique_ptr<MyClass> ptr2 = ptr1; // 错误:不能复制 unique_ptrstd::unique_ptr<MyClass> ptr2 = std::move(ptr1); // 移动所有权if (!ptr1) {std::cout << "ptr1 is empty\n";}if (ptr2) {ptr2->sayHello();}return 0;
}
输出结果
MyClass constructed
Hello
ptr1 is empty
Hello
MyClass destroyed
内存管理机制
-  独占所有权: - unique_ptr在同一时间只能有一个所有者,禁止复制操作。
- 通过移动操作将所有权转移。
 
-  自动释放内存: - 当 unique_ptr超出作用域或被销毁时,自动调用删除器释放对象内存。
 
- 当 
总结
- unique_ptr提供了一种安全的、自动的内存管理方式,确保对象不会被多个指针共享。
- 它通过禁止复制和允许移动操作实现独占所有权。
- 使用删除器在 unique_ptr销毁时释放对象内存,防止内存泄漏。
代码实现
这里是一个简单的unique_ptr的实现原理代码示例。这个示例包含了unique_ptr的核心功能,包括独占所有权、移动语义以及自动内存管理。
#include <iostream>
#include <utility> // for std::movetemplate<typename T>
class UniquePtr {
private:T* ptr; // 原始指针public:// 构造函数explicit UniquePtr(T* p = nullptr) : ptr(p) {}// 禁止复制构造函数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;}// 析构函数~UniquePtr() {delete ptr; // 释放资源}// 重载 * 操作符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) {if (ptr != p) {delete ptr; // 释放当前持有的资源ptr = p; // 设置新的指针}}
};class MyClass {
public:MyClass() { std::cout << "MyClass constructed\n"; }~MyClass() { std::cout << "MyClass destroyed\n"; }void sayHello() { std::cout << "Hello\n"; }
};int main() {UniquePtr<MyClass> ptr1(new MyClass());ptr1->sayHello();// UniquePtr<MyClass> ptr2 = ptr1; // 错误:不能复制 unique_ptrUniquePtr<MyClass> ptr2 = std::move(ptr1); // 移动所有权if (!ptr1.get()) {std::cout << "ptr1 is empty\n";}if (ptr2.get()) {ptr2->sayHello();}return 0;
}
代码说明
-  构造函数: - UniquePtr(T* p = nullptr) : ptr(p) {}:构造函数初始化原始指针。
 
-  禁止复制: - UniquePtr(const UniquePtr&) = delete;:禁止复制构造函数。
- UniquePtr& operator=(const UniquePtr&) = delete;:禁止复制赋值操作符。
 
-  移动语义: - UniquePtr(UniquePtr&& other) noexcept:移动构造函数,从其他- UniquePtr转移所有权,并将源指针置空。
- UniquePtr& operator=(UniquePtr&& other) noexcept:移动赋值操作符,从其他- UniquePtr转移所有权,并将源指针置空。
 
-  析构函数: - ~UniquePtr():析构函数释放资源。
 
-  智能指针接口: - T& operator*() const:重载解引用操作符。
- T* operator->() const:重载箭头操作符。
- T* get() const:返回原始指针。
- T* release():释放所有权并返回原始指针。
- void reset(T* p = nullptr):重新设置指针,释放当前持有的资源。
 
输出结果
MyClass constructed
Hello
ptr1 is empty
Hello
MyClass destroyed
总结
- UniquePtr确保对象在同一时间只有一个所有者,防止多个指针共享。
- 通过移动语义,可以将所有权从一个 UniquePtr转移到另一个。
- UniquePtr自动管理对象生命周期,当智能指针超出作用域时自动释放资源。