C++11-独占指针unique_ptr原理实现

独占指针(unique_ptr)是C++11标准引入的一种智能指针,用于独占管理动态分配对象的生命周期。unique_ptr确保对象在同一时间只有一个所有者,防止对象被多个指针共享。下面是unique_ptr的实现原理及其内存管理机制。

unique_ptr 的基本原理

  1. 独占所有权

    • unique_ptr 独占对象的所有权,不能被复制,但可以移动。
    • 通过移动语义,可以将所有权从一个 unique_ptr 转移到另一个。
  2. 自动内存管理

    • unique_ptr 被销毁时,它所管理的对象也会被销毁,自动释放内存。

实现原理

  1. 基本结构

    • unique_ptr 是一个模板类,包含一个原始指针和一个删除器。
    • 删除器是一个可调用对象(如函数指针、函数对象或 std::default_delete),用于在 unique_ptr 销毁时释放对象。
  2. 构造与析构

    • 构造函数:接受一个原始指针,默认使用 std::default_delete 作为删除器。
    • 析构函数:调用删除器释放对象。
  3. 禁止复制

    • unique_ptr 禁止复制构造和复制赋值操作。
    • 通过删除复制构造函数和复制赋值操作符来实现。
  4. 移动语义

    • 允许移动构造和移动赋值操作。
    • 通过移动构造和移动赋值操作符将所有权转移到另一个 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_ptr
    std::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

内存管理机制

  1. 独占所有权

    • unique_ptr 在同一时间只能有一个所有者,禁止复制操作。
    • 通过移动操作将所有权转移。
  2. 自动释放内存

    • unique_ptr 超出作用域或被销毁时,自动调用删除器释放对象内存。

总结

  • unique_ptr 提供了一种安全的、自动的内存管理方式,确保对象不会被多个指针共享。
  • 它通过禁止复制和允许移动操作实现独占所有权。
  • 使用删除器在 unique_ptr 销毁时释放对象内存,防止内存泄漏。

代码实现

这里是一个简单的unique_ptr的实现原理代码示例。这个示例包含了unique_ptr的核心功能,包括独占所有权、移动语义以及自动内存管理。

#include <iostream>
#include <utility> // for std::move

template<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_ptr
    UniquePtr<MyClass> ptr2 = std::move(ptr1); // 移动所有权

    if (!ptr1.get()) {
        std::cout << "ptr1 is empty\n";
    }

    if (ptr2.get()) {
        ptr2->sayHello();
    }

    return 0;
}

代码说明

  1. 构造函数

    • UniquePtr(T* p = nullptr) : ptr(p) {}:构造函数初始化原始指针。
  2. 禁止复制

    • UniquePtr(const UniquePtr&) = delete;:禁止复制构造函数。
    • UniquePtr& operator=(const UniquePtr&) = delete;:禁止复制赋值操作符。
  3. 移动语义

    • UniquePtr(UniquePtr&& other) noexcept:移动构造函数,从其他UniquePtr转移所有权,并将源指针置空。
    • UniquePtr& operator=(UniquePtr&& other) noexcept:移动赋值操作符,从其他UniquePtr转移所有权,并将源指针置空。
  4. 析构函数

    • ~UniquePtr():析构函数释放资源。
  5. 智能指针接口

    • 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 自动管理对象生命周期,当智能指针超出作用域时自动释放资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值