《C++沉思录》 第六章 句柄 第一部分

本文探讨了C++中解决继承体系中容器对象管理的问题,通过代理类和句柄类的设计思想。代理类用于封装基类指针,控制对象生命周期,而句柄类则进一步优化,允许多个句柄指向同一对象,避免不必要的复制。通过一个维修人员与家庭的比喻,解释了句柄类如何跟踪使用计数来决定对象何时释放。
摘要由CSDN通过智能技术生成

      简单回顾一下第五章节,Andrew Koening向我们提出了一个问题,在一个继承体系中,如何设计一个容器可以容纳各个不同的子类对象。显然无法使用基类对象数组,如果是抽象基类,没有办法进行实例化。很自然的我们容易想到可以使用基类指针,但这样对象内存管理便交于用户了,容易造成很多麻烦问题。为了解决此问题,Koening使用了代理类。

     什么是代理类呢,简单来说,就是封装了基类指针并可以提供所有功能接口的类。在代理类的构造过程中,使用对象的指针初始化代理类的基类指针成员,并在析构函数中释放代理的对象内存。仔细思考一下,其实一个代理类对象可以代理多个类型不同的对象,但是否会有用,现在仍在思考中。

     好了,进入第六章 句柄,Koening又提出了一个问题,代理类的复制会造成其代理的对象的复制,这个在很多场合下是不合理的,如何可以具有代理功能,而又避免不必要的复制呢,"句柄类" is the answer.  那么句柄类应该具备些什么呢,首先句柄类应该和代理类一样具备对绑定对象的生存控制权。这个取决于句柄类的构造函数,要不然句柄类可以直接构造其绑定的对象,要不然就需要一个存在的对象的来创建一个副本并绑定到副本上。 到目前为止,句柄和前面的代理没什么区别。

     句柄区别于代理的是:允许多个句柄绑定到同一个对象上,当复制句柄的时候,并不发生对象的复制。这个的常见应用场景是我们以一个句柄作为函数的参数,我们可以做到只复制句柄而不复制对象,怎样做到呢。来看一个简单模型:A, B, C三个家庭在同一小区,在一天内都向物业的维修人员提出了维修请求,维修人员D负责三家的维修工作。A,B, C在这一天都与D建立了联系(电话预约之类的),当D给A维修完时,A对D说:“你可以走了”,但D并没有真正的离开小区,他还需要给B,C家进行维修。 同样,假设三个句柄A,B,C都与D进行了绑定,当A使用完毕说释放掉D的时候,D当然可以释放掉也可以不释放掉,因为D的工作还有B,C。这个就相当于维修人员给A维修完毕后,返回家,接着再返回来给B,C维修,我想维修人员不会那么傻,来回跑。因此D在这种情况下不会释放,但是不释放得有依据,我什么时候释放。维修人员自己有记录的,谁打了电话,当所有的电话记录中的维修处理完毕后,维修人员才离开。但如果维修人员离开后,再有人打电话过来,他当然需要再返回去。因此对象D需要有个记录去维护以便知道什么时间释放自己。那这个记录为什么需要对象来维护呢,很简单,A家庭不关心维修人员是否需要给其他家庭进行维修,我只关心你需要给我维修。因此记录只能由维修人员来维护。

     回到对象D,对象D需要维护一个记录来确定自己是否要释放掉,那这个记录需要些什么么,需要关心谁绑定了我么,不需要。这个多少跟我们前面的场景有所差别,维修人员需要在收到通知后主动去提供服务,而我们的对象不需要,我们是被使用者。对于对象来说,谁来使用我没有太大差别。因此不需要关心谁来使用对象,对象只需要一个计数,增加了一个使用者,计数增加1,使用完毕,计数减一,如果计数为0说明没有人使用了,我可以去了。

    koening给我们讲叙的计数要稍复杂些,如果我们的对象类是我们刚设计的,那我们可以加入计数。但是对于一个已经存在的对象类,我们往往不会修改其实现,这个时候就需要定义一个新类来容纳原有对象和计数。好了理清这个思路,后面koening后面就讲了如何实现以及一些技巧性东西。不在赘叙。

 

      

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值