Administrator
发布于 2025-09-12 / 9 阅读
0
0

线程安全引用计数和使用RAII的智能指针包装器


class ThreadSafeRefCounted {
public:
    ThreadSafeRefCounted() noexcept      : refCount(0) {}

	//禁用拷贝和移动
	ThreadSafeRefCounted(const ThreadSafeRefCounted&) = delete;
	ThreadSafeRefCounted(ThreadSafeRefCounted&&) = delete;
	ThreadSafeRefCounted& operator=(const ThreadSafeRefCounted&) = delete;
	ThreadSafeRefCounted& operator=(const ThreadSafeRefCounted&&) = delete;

	//增加引用计数
    void addRef() noexcept {
        refCount.fetch_add(1, std::memory_order_relaxed);
    }

	//减少引用计数, 应用计数为1时销毁对象
    void release()   noexcept  {
        if (refCount.fetch_sub(1, std::memory_order_acq_rel) == 1) {
            delete this;
        }
    }

	//获取当前引用计数(主要用于调试)
	int getRefCount() const noexcept{
		return refCount.load(std::memory_order_relaxed);
	}
    
protected:
    virtual ~ThreadSafeRefCounted() = default;
    
private:
	
    std::atomic<unsigned int> refCount;
};


//使用RAII的智能指针包装器
template<typename T>
class RefCountedPtr{
public:
	//构造函数
    explicit RefCountedPtr(T* ptr = nullptr) noexcept : ptr_(ptr) {
		if(ptr_)		{
			ptr_->addRef();
		}
	}
	
	//拷贝构造函数
	RefCountedPtr(const RefCountedPtr& other) noexcept :ptr_(other.ptr_) {
		if(ptr_)		{
			ptr_->addRef;
		}
	}
	//移动构造函数
	RefCountedPtr(RefCountedPtr&& other) noexcept : ptr_(other.ptr_){
		other.ptr_ = nullptr;
	}
	
	//析构函数
	~RefCountedPtr()	{
		if(ptr_)		{
			ptr_->release();
		}
	}
	//拷贝赋值运算符
	RefCountedPtr& operator=(const RefCountedPtr& other) noexcept	{
		if(this != &other)		{
            		// 先增加新对象的引用计数,再减少旧对象的
			if(other.ptr_)			{
				other.ptr_->addRef();
			}
			if(ptr_)			{
				ptr_->release();
			}
			ptr_ = other.ptr_;
		}
		return *this;
	}
	
	

	
    	// 移动赋值运算符
	RefCountedPtr& operator=( RefCountedPtr&& other) noexcept{
		if(this != &other)		{
			if(ptr_)			{
				ptr_->release();
			}
			ptr_ = other.ptr_;
			other.ptr_ = nullptr;
		}
	}


	//解引用运算符
	T& operator*() const noexcept{
		return *ptr_;
	}
	//箭头运算符
	T* operator->()const noexcept	{
		return ptr_;
	}
	
	//获取原始指针
	T* get() const noexcept{
		return ptr_;
	}
	//重置指针
	void reset(T* ptr = nullptr) noexcept{
		if(ptr_)		{
			ptr_->release();
		}
		ptr_ = ptr;
		if(ptr_)		{
			ptr_->addRef;
		}
	}
	//布尔转换
	explicit operator bool() const noexcept{
		return ptr_ != nullptr;
	}
		
	//交换
	void swap(RefCountedPtr& other) noexcept{
		std::swap(ptr_,other.ptr_);
	}
	
private:
	T*	ptr_;
};


评论