本文共 2059 字,大约阅读时间需要 6 分钟。
自己写了一个shared_ptr的实现。如有错漏,还望指摘。
(PS:我最近突然在想,是不是应该用锁而不是原子类?因为原子类没办法和指针一起绑定成原子操作。比如:一个线程调用析构函数时,自减引用计数之后,还没来得及释放内存时,如果有另一个线程这个时候获取了指针,是不是就会出问题?)templateclass 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; }};
转载地址:http://gtxzi.baihongyu.com/