C++ shared_ptr的实现

自己写了一个shared_ptr的实现。如有错漏,还望指摘。
(PS:我最近突然在想,是不是应该用锁而不是原子类?因为原子类没办法和指针一起绑定成原子操作。比如:一个线程调用析构函数时,自减引用计数之后,还没来得及释放内存时,如果有另一个线程这个时候获取了指针,是不是就会出问题?)

template<class T>
class MySharedPtr
{
     
private:
    T* ptr = nullptr;                 //指针
    std::atomic_uint* num = nullptr;  //引用计数

public:
    constexpr MySharedPtr() noexcept {
     }                //无参构造函数
    constexpr MySharedPtr(std::nullptr_t) noexcept {
     }  //参数为空指针
    MySharedPtr(T* p) : ptr(p) {
                            //有参构造函数
        num = new std::atomic_uint(1);
    };
    MySharedPtr(const MySharedPtr& p) noexcept : ptr(p.ptr), num(p.num) {
      //拷贝构造,参数为左值
        //如果不为空指针,引用计数自增
        if(num)
            ++(*num);
    };
    //参数为右值的拷贝构造
    MySharedPtr(MySharedPtr&& p) noexcept {
     
        std::swap(ptr, p.ptr);
        std::swap(num, p.num);
    }
    //赋值操作符
    MySharedPtr& operator = (const MySharedPtr& _right) noexcept {
     
        //如果参数不是空指针,则引用计数自增
        //先自增参数的引用计数是为了防止参数就是自身的情况
        if(_right.num)
            ++(*_right.num);
        //处理原本指向的内存
        //如果num指针不为空,且没有其他引用,则释放空间
        if(num && !(--(*num))){
     
            delete num;
            delete ptr;
        }
        //指向新内存
        ptr = _right.ptr;
        num = _right.num;
        return *this;
    }
    //赋值操作符,参数为右值
    MySharedPtr& operator = (MySharedPtr&& _right) noexcept {
     
        std::swap(ptr, _right.ptr);
        std::swap(num, _right.num);
        return *this;
    }
    //析构
    ~MySharedPtr() noexcept {
     
        //如果num指针不为空,且没有其他引用,则释放空间
        if (num && !(--(*num)))
        {
     
            delete ptr;
            ptr = nullptr;

            delete num;
            num = nullptr;
        }
    }
    //重载->操作符
    T* operator ->() const noexcept
    {
     
        return ptr;
    }
    //重载*操作符
    T& operator *() const noexcept
    {
     
        return *ptr;
    }
    //重载[]操作符
    T& operator [] (long long index) const noexcept
    {
     
        return ptr[index];
    }
    //获取指针
    T* get()
    {
     
        return ptr;
    }
    //获取引用计数,空指针则返回0
    unsigned int use_count()
    {
     
        return num ? *num : 0;
    }
};

你可能感兴趣的:(C++学习笔记,c++,智能指针)