C++ 手撕--共享式智能指针(shared_ptr)的简单实现

C++ 手撕--共享式智能指针(shared_ptr)的简单实现

共享式智能指针(shared_ptr):

#include <iostream>
#include <atomic>
#include <mutex>

template <typename T>
class Shared_ptr {
private:
    T* ptr;  // 指向管理的资源
    std::atomic<int>* ref_count;  // 原子引用计数
    std::mutex* mtx;  // 互斥锁保护资源访问

    // 释放资源
    void release() {
        bool shouldDelete = false;
        {
            std::lock_guard<std::mutex> lock(*mtx);
            if (ref_count && --(*ref_count) == 0) {
                delete ptr;
                delete ref_count;
                shouldDelete = true;
            }
        }
        // 在锁外部删除互斥锁,避免死锁
        if (shouldDelete) {
            delete mtx;
        }
    }

public:
    // 默认构造函数
    Shared_ptr() : ptr(nullptr), ref_count(new std::atomic<int>(0)), mtx(new std::mutex) {}

    // 带指针的构造函数
    explicit Shared_ptr(T* p) : ptr(p), ref_count(new std::atomic<int>(1)), mtx(new std::mutex) {}

    // 拷贝构造函数
    Shared_ptr(const Shared_ptr& other) {
        std::lock_guard<std::mutex> lock(*other.mtx);
        ptr = other.ptr;
        ref_count = other.ref_count;
        mtx = other.mtx;
        (*ref_count)++;
    }

    // 移动构造函数
    Shared_ptr(Shared_ptr&& other) noexcept {
        std::lock_guard<std::mutex> lock(*other.mtx);
        ptr = other.ptr;
        ref_count = other.ref_count;
        mtx = other.mtx;
        other.ptr = nullptr;
        other.ref_count = nullptr;
        other.mtx = nullptr;
    }

    // 拷贝赋值操作符
    Shared_ptr& operator=(const Shared_ptr& other) {
        if (this != &other) {
            release(); // 释放当前持有的资源
            std::lock_guard<std::mutex> lock(*other.mtx);
            ptr = other.ptr;
            ref_count = other.ref_count;
            mtx = other.mtx;
            (*ref_count)++;
        }
        return *this;
    }

    // 移动赋值操作符
    Shared_ptr& operator=(Shared_ptr&& other) noexcept {
        if (this != &other) {
            release(); // 释放当前持有的资源
            std::lock_guard<std::mutex> lock(*other.mtx);
            ptr = other.ptr;
            ref_count = other.ref_count;
            mtx = other.mtx;
            other.ptr = nullptr;
            other.ref_count = nullptr;
            other.mtx = nullptr;
        }
        return *this;
    }

    // 获取引用计数
    int use_count() const {
        return ref_count ? ref_count->load() : 0;
    }

    // 获取指针值
    T* get() const {
        std::lock_guard<std::mutex> lock(*mtx);
        return ptr;
    }

    // 重置指针
    void reset(T* p = nullptr) {
        release(); // 释放当前持有的资源
        {
            ptr = p;
            if (ptr) {
                ref_count = new std::atomic<int>(1);
                mtx = new std::mutex;
            }
            else {
                ref_count = new std::atomic<int>(0);
                mtx = new std::mutex;
            }
        }
    }

    // 重载*和->操作符
    T& operator*() const { return *get(); }
    T* operator->() const { return get(); }

    // 析构函数
    ~Shared_ptr() {
        release();
    }
};
posted @ 2024-11-02 19:38  风枕子  阅读(455)  评论(0)    收藏  举报