Loading

C++中的引用计数机制

C++中的引用计数机制

引用计数是为了防止内存泄露而产生的。基本想法是对于动态分配的对象,进行引用计数,每当增加一次对同一个对象的引用,那么引用对象的引用计数就会增加一次,每删除一次引用,引用计数就会减一,当一个对象的引用计数减为零时,就自动删除指向的堆内存。

在C++中,手动释放资源,不是最佳实践。因为我们很有可能就忘记了去释放资源而导致泄露。所以通常的做法是对于一个对象而言,我们在构造函数的时候申请空间,而在析构函数(在离开作用域时调用)的时候释放空间,也就是我们常说的 RAII 资源获取即初始化技术。凡事都有例外,我们总会有需要将对象在自由存储上分配的需求,在传统 C++ 里我们只好使用 new 和 delete 去对资源进行释放。

引用计数是这样一个技巧,它允许多个有相同值的对象共享这个值的实现。
这个技巧有两个常用动机:

  1. 简化跟踪堆中的对象的过程
  2. 第二个动机是如果很多对象有相同的值,更好的办法是让所有的对象共享这个值的实现。这么做不但节省内存,而且可以使得程序运行更快。
class String { 
public: 
  String(const char *value = "");
  String& operator=(const String &rhs);
private:
  char *data;
};
String a = b = c = d = e = "Hello";

根据这个实现,我们可以推测,这 5 个对象及其值如下:

而我们希望它是这样的
只存储了一个“Hello”的拷贝,所有具有此值的 String 对象共享其实现。但这太过理想。我们需要追踪记录有多少个对象共享此值,只要还有一个对象指向它,我们就不该销毁实值hello。 这就用到了引用计数机制。

引用计数的实现

C++11 引入了智能指针的概念,使用了引用计数的机制,让程序员不再需要关心手动释放内存。这些智能指针就包括 std::shared_ptr/std::unique_ptr/std::weak_ptr。

在C++11中新增的智能指针shared_ptr中采用引用计数的方法,记录当前内存资源被多少个智能指针引用。该引用计数的内存在堆上分配。当新增一个时引用计数加1,当过期时引用计数减1。只有引用计数为0时,智能指针才会自动释放引用的内存资源。

以下是智能指针shared_ptr的简单实现:

template<typename T>
class SharedPtr {
public:
	// 构造函数
	SharedPtr(T *ptr = nullptr) : m_ptr(ptr), m_count(new int(1)) {}
	// 拷贝构造函数
	SharedPtr(const SharedPtr<T>& rhs) {
		this->m_count = rhs.m_count;
		this->m_ptr = rhs.m_ptr;
		++(*m_count);
	}
	// 赋值运算符
  
	SharedPtr<T>& operator=(const SharedPtr<T>& rhs) {
		(*rhs.m_count)++;
		if (--(*m_count) == 0) {
			delete m_ptr;
			ptr = nullptr;
			delete m_count;
			m_count = nullptr;
		}
		m_ptr = rhs.m_count;
		m_count = rhs.m_count;
		return *this;
	}
	T& operator*() {
		return *m_ptr;
	}
	T* operator->() {
		return m_ptr;
	}


	~SharedPtr() {
		if (--(*m_cout) == 0) {
			delete m_ptr;
			m_ptr = nullptr;
			delete m_count;
			m_count = nullptr;
		}

	}

private:
	T* m_ptr;   // 封装一个普通指针
	int *m_count; // 指向引用计数
};
posted @   潇洒哥lh  阅读(808)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示