`
king_c
  • 浏览: 225467 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

c++引用计数的本质

阅读更多

为什么要用引用计数? 

       场景:代码里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,这里就写一点思路,具体代码就略过了。

        

 

分享到:
评论

相关推荐

    C++实例——垃圾清理系统

    在实际的“垃圾清理系统”实例中,可能会包含一个管理对象池的类,这个类使用智能指针来持有对象,并通过某种策略(如引用计数、定时清理等)决定何时释放不再使用的对象。同时,这个系统可能还需要考虑到线程安全,...

    C++绝密面试题

    **解析**:引用和指针在很多情况下可以互换使用,但它们有本质上的不同。指针是一个可以存储地址的变量,而引用则是某个对象的别名。 #### 8. 输入输出流操作符 **问题**:何时使用输入输出流操作符 `和 `>>`? *...

    COM本质论 c++

    QueryInterface用于获取组件支持的其他接口,AddRef和Release则用于管理接口引用计数,确保组件资源的正确释放。 COM还引入了组件注册的概念,通过注册表来记录组件的相关信息,如类ID、接口ID等,使得系统能够找到...

    More_Effective_C++(WQ版).pdf

    - 引用计数 - 代理类 - 让函数根据一个以上的对象来决定怎么虚拟 6. **杂项:** - 在未来时态下开发程序 - 将非尾端类设计为抽象类 - 如何在同一程序中混合使用C++和C - 让自己习惯使用标准C++语言 #### ...

    C++常见问题解答。。。。。。。。。

    这意味着不仅要复制对象的引用计数或其他轻量级信息,还要复制对象内部的所有数据成员。对于复杂的对象,可能还需要重载赋值运算符来确保正确的行为。 #### 24. 编写代码时应遵循哪些编码风格? 编写高质量的C++...

    c++笔试面试宝典2009

    引用在C++中是一种特殊的变量类型,本质上是现有变量的别名。使用引用可以避免复制大量数据,提高程序效率。然而,申明引用时必须初始化,并且不能改变引用的对象,这些特性要求开发者在使用时需格外小心,以免引入...

    Android垃圾回收实质内容解析PPT.ppt

    当一个`wp`对象创建时,它会增加对象的弱引用计数,但不会影响对象的强引用计数。例如,`wp<CameraHardwareInterface> CameraHardwareStub::singleton`这行代码创建了一个弱引用,即使没有强引用指向`...

    侯捷译Scott Meyers的 More Effecitve C++

    - 引用计数是一种常用的内存管理技术,用于跟踪指向同一对象的指针数量。 - 当计数降为零时,对象会被自动销毁。 - **Item 30: 代理类** - 代理类可以作为另一个类的代理,用于控制对其的访问或提供额外的功能。...

    C和C++标准库源代码

    源代码涉及到引用计数和自动释放的实现。 通过阅读C和C++标准库的源代码,我们可以学习到如何编写高效、健壮的代码,同时理解语言特性在实际应用中的表现。这不仅有助于提升编程技巧,也能加深对语言本质的理解。...

    c++11 智能指针(csdn)————程序.pdf

    智能指针通过引用计数来管理堆内存,当最后一个指向对象的智能指针被销毁时,自动释放对象。C++11 中有四种智能指针:auto_ptr、unique_ptr、shared_ptr、weak_ptr,其中 auto_ptr 已被弃用。 1. shared_ptr(共享...

    C++指针及数组应用

    数组名实质上是数组首元素的地址,数组名可以转换为指向数组首元素的指针。在C++中定义数组时,必须明确数组的类型以及大小。数组元素通过下标访问,下标从0开始计数。数组一旦定义,其大小就固定不变,且不能通过...

    奇妙的C++——智能指针

    3. **std::weak_ptr**:std::weak_ptr是std::shared_ptr的辅助类,它不增加对象的引用计数,而是保持对对象的弱引用。这避免了循环引用的问题,当对象被所有std::shared_ptr释放后,std::weak_ptr尝试访问对象时会抛...

    C++智能指针.pdf

    shared_ptr内部维护一个引用计数,当引用计数归零时,对象会被自动删除。它提供了一个便捷的初始化方式make_shared,以确保安全高效地分配内存。 - 初始化:可以使用`make_shared`函数,如`shared_ptr<int> pint =...

    More Effective C++.pdf

    - 指针和引用都是C++中用于存储其他变量地址的方式,但它们有着本质的区别。指针可以被重新赋值指向不同的变量,而引用一旦初始化后就不能改变所引用的对象。 - 使用引用通常比指针更为安全,因为它不能被设为NULL...

Global site tag (gtag.js) - Google Analytics