《c++沉思录》第七章 句柄:第二部分

       在第六章中,一直跟着书走,并没有深入思考第六章中实现的句柄,一看第七章还是句柄,心生怀疑难道句柄还没有结束么,之前的设计有什么问题么,唉是真有,第六章中我们要实现句柄操作需要包括三个部分:原数据类,数据的引用计数封装类, 句柄类。问题出在引用计数这部分,我们的封装类使用的是具体类,没有办法做到通用,我们仍然必须回到基类指针上,我们可以让中间的类封装基类指针,这个是可以的,通过修改实现是没有问题的,即UPoint中同样使用Point* p,复杂一些,但仔细考虑一下结构Handle 中使用Upoint * p,Upoint其实就是数据和计数,可以将Upoint拆解,将指针传递给Upoint的每个数据成员,将大结构分散,于是就成了7.2节中分离引用计数的结构。但效果截然不同,我们拥有了Point* p 指针。走到这一步我们来看一下句柄类的具体实现。

   

    从构造函数开始。我们需要什么样的构造函数,我们的句柄类不是一个通用的类,它仍然是绑定某特定类的指针(当然可以是基类)。因此构造的过程仍然会需要一个特定的类指针。此时我不得不打断自己的思路,如果我们绑定的是一个void*p 指针呢,貌似是一个不错的念头。但如果这样,我们的构造函数肯定需要一个指针了。而且我们没有办法控制生存期,我们没有办法拥有对象的控制权,因为我们绑定的永远都是一个已经存在的对象而不是副本,我们没有办法去初始化我们的引用计数。因为其他的句柄绑定到该对象时可以不为我们所知,如果非要得到对象的副本也可以象代理类那样的方法提供一个copy函数,具体的实现没有再去想,估计也不甚理想,总要去坡坏原来的类,要想完全得到绑定对象的控制权我们必须有能力得到副本,这就限定了我们句柄绑定的类必须拥有构造函数。抽象类是无法进行句柄绑定的。这点是与代理类的差异。好了终于回到我们的实现上来了。

构造函数的作用:(1)得到对象的副本(2)将引用计数初始化为1。 具体句柄类要提供的构造函数取决于被绑定的类的构造函数。

当然有个特殊的构造函数需要考虑,拷贝构造函数。用一个句柄初始化另一个句柄,含义是什么呢,就是将后者也绑定到前者绑定的对象上。自然引用计数需要加1了。

有了拷贝构造函数,接下来就是赋值,赋值是有些麻烦的,含义是,一个句柄重新绑定到另一个句柄上,过程就是将前者解绑定然后绑定到后者绑定的对象上。句柄的赋值和对象的赋值是有差异的,对象的赋值我们需要考虑自身赋值的情况,只有当不是自我赋值的时候才真正发生赋值行为。而句柄是只要句柄存在,它的对象肯定存在。所以即使绑定的对象相同,解绑定的过程也不会将对象删除的。

析构函数的含义就是解绑定,比较简单。解绑定时当引用计数为0便删除引用计数和绑定对象。

 

到此我们总结一下:代理类做到了在一个继承体系中使用基类容器(包括抽象基类),前提是需要原来的类提供一个拷贝自身的函数。

句柄类做到了可以使用基类容器(不能是抽象基类),并避免了对象的复制操作。

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值