为什么要用引用计数?
场景:代码里X是一个非常重要的资源,模块A,B,C都有对其指针的引用,那么为了不出现内存泄露,常规的代码我们要怎么写?
1. A 模块用完X时,需要检查B,C是否还在引用X,如果B,C有一个在用,那么X只要删除掉对A的引用就可以了,
如果B,C对A都已经没有引用了,那么A需要删除对X的引用时,要同时清除掉X。
2.同样B,C在用完X时,也要重复做1里面的事情。
这样,代码将会多了许多的逻辑判断,同时模块B,C还需要对模块A提供查询是否在引用X的接口。
可以不这么恶心吗?
思考:能否A在释放X前,不需要知道是谁在引用X,只要知道有多少人在引用X?
回答:是的,如果只有我用X,那么我就直接删除,如果还有其他人用,我就什么都不管,只要去除掉对X的引用就可以了。 情况就会变的好一些。
那么如何做到能知道资源的引用次数那?
这就需要对每一个资源X的都有一个的计数,这个计数是和资源X的生命周期息息相关的。
那么如何来管理这个计数?怎么能在有模块引用资源X的时候,计数++,模块释放资源X的时候计数--那?
这个就有一定难度了,引用的方式会有很多种,比如 A = X; A.push_back(X); A[100] = X; ...
当然我们可以在代码里的每一处增加和释放资源引用的地方,都加上代码count++,count--;但这亦然很麻烦,维护成本很高。
如何简单些?
能否把对资源的引用和释放,看成是对一个类的拷贝和销毁来完成? 弄一个代理类,里面封装好计数和资源X。
把所有对资源X的引用都理解成对代理类的引用,对代理类的引用都理解成对代理类的拷贝,对代理的释放就是销毁代理类。
这样我们只需要在代理类的拷贝函数里count++ , 代理类的析构做count--就好了。
如果代理类的资源引用计数count 减为0,就看成所有人都释放了对资源X的引用,这时由代理类来完成对资源的销毁。
这样下来,事情就简化了很多。 所以学会抽象是多么重要的一件事情。
一点code:
class RefPtr { size count; X * ptr; } class Proxy { RefPtr* ptr; };
1 Proxy里面需要重载=, 拷贝构造
2 Proxy需要提供访问ptr的接口
3 Proxy需要在拷贝的地方增加计数,析构的时候判断是否删除ptr
--- ko,这里就写一点思路,具体代码就略过了。
相关推荐
在实际的“垃圾清理系统”实例中,可能会包含一个管理对象池的类,这个类使用智能指针来持有对象,并通过某种策略(如引用计数、定时清理等)决定何时释放不再使用的对象。同时,这个系统可能还需要考虑到线程安全,...
**解析**:引用和指针在很多情况下可以互换使用,但它们有本质上的不同。指针是一个可以存储地址的变量,而引用则是某个对象的别名。 #### 8. 输入输出流操作符 **问题**:何时使用输入输出流操作符 `和 `>>`? *...
QueryInterface用于获取组件支持的其他接口,AddRef和Release则用于管理接口引用计数,确保组件资源的正确释放。 COM还引入了组件注册的概念,通过注册表来记录组件的相关信息,如类ID、接口ID等,使得系统能够找到...
- 引用计数 - 代理类 - 让函数根据一个以上的对象来决定怎么虚拟 6. **杂项:** - 在未来时态下开发程序 - 将非尾端类设计为抽象类 - 如何在同一程序中混合使用C++和C - 让自己习惯使用标准C++语言 #### ...
这意味着不仅要复制对象的引用计数或其他轻量级信息,还要复制对象内部的所有数据成员。对于复杂的对象,可能还需要重载赋值运算符来确保正确的行为。 #### 24. 编写代码时应遵循哪些编码风格? 编写高质量的C++...
引用在C++中是一种特殊的变量类型,本质上是现有变量的别名。使用引用可以避免复制大量数据,提高程序效率。然而,申明引用时必须初始化,并且不能改变引用的对象,这些特性要求开发者在使用时需格外小心,以免引入...
当一个`wp`对象创建时,它会增加对象的弱引用计数,但不会影响对象的强引用计数。例如,`wp<CameraHardwareInterface> CameraHardwareStub::singleton`这行代码创建了一个弱引用,即使没有强引用指向`...
- 引用计数是一种常用的内存管理技术,用于跟踪指向同一对象的指针数量。 - 当计数降为零时,对象会被自动销毁。 - **Item 30: 代理类** - 代理类可以作为另一个类的代理,用于控制对其的访问或提供额外的功能。...
源代码涉及到引用计数和自动释放的实现。 通过阅读C和C++标准库的源代码,我们可以学习到如何编写高效、健壮的代码,同时理解语言特性在实际应用中的表现。这不仅有助于提升编程技巧,也能加深对语言本质的理解。...
智能指针通过引用计数来管理堆内存,当最后一个指向对象的智能指针被销毁时,自动释放对象。C++11 中有四种智能指针:auto_ptr、unique_ptr、shared_ptr、weak_ptr,其中 auto_ptr 已被弃用。 1. shared_ptr(共享...
数组名实质上是数组首元素的地址,数组名可以转换为指向数组首元素的指针。在C++中定义数组时,必须明确数组的类型以及大小。数组元素通过下标访问,下标从0开始计数。数组一旦定义,其大小就固定不变,且不能通过...
3. **std::weak_ptr**:std::weak_ptr是std::shared_ptr的辅助类,它不增加对象的引用计数,而是保持对对象的弱引用。这避免了循环引用的问题,当对象被所有std::shared_ptr释放后,std::weak_ptr尝试访问对象时会抛...
shared_ptr内部维护一个引用计数,当引用计数归零时,对象会被自动删除。它提供了一个便捷的初始化方式make_shared,以确保安全高效地分配内存。 - 初始化:可以使用`make_shared`函数,如`shared_ptr<int> pint =...
- 指针和引用都是C++中用于存储其他变量地址的方式,但它们有着本质的区别。指针可以被重新赋值指向不同的变量,而引用一旦初始化后就不能改变所引用的对象。 - 使用引用通常比指针更为安全,因为它不能被设为NULL...