运用智能指针的一些思路


首先,智能指针是模拟真实指针,但是负责管理资源释放的类。

第一,为何要用指针,而不是直接用对象。指针是实现多态的基础,同时具备灵活绑定性的一种类型(引用也可以实现多态,但是不具备灵活绑定性。而且你不能在堆中申请一块内存,然后绑定,然后他就乖乖帮你释放,做不到这种效果,所以他并不比指针更强大,却很容易误导人写出错误的程序)。因此,用指针,主要目的就是实现多态,次要原因是需要后期绑定,比如在建立对象的时候不能准确得知这部分数据(但是或许用一个stl容器包装会是更好的设计)。

第二,智能指针不等于共享对象的潜台词。在对象设计中,拷贝往往是深拷贝才符合语义,那么这时候实现共享的智能指针一点意义也没有(或者作为一种优化)。但如果是常量型数据成员的设计需求,可以用共享型智能指针来提高拷贝速度。拷贝构造是静态的,不能支持多态,因此非共享型的智能指针的模板类型,就必须提供一种虚拟拷贝构造的方法。

第三,在c++中,构造对象即申请资源这个范式很流行,所以我认为,作为智能指针,他所负责资源管理的是在他创建的时候所同时绑定的对象。除此之外,必须通过显示的成员函数调用来改变这种绑定关系,而不能隐式,在无法看到这是一个智能指针,而不是真是指针的情况下改变这种绑定。对于这种构造则绑定的需求,其实已经在c 99中得到体现,一种xx指针,锁定在一个堆对象中。

第四,智能指针的默认构造应该是怎样的?stl容器需要默认构造函数,如果希望能与stl 容器配合,那么智能指针就需要设计一个默认构造函数。 默认清零,或者默认生成对应类型的对象。清零和真实指针比较类似,同时保证了抛出异常的准确性。用默认类型对象,可以更加接近非指针容器,同时也保留了以后修改的绑定对象可能。

第五,共享型智能指针作为优化手段,可以保证读共享,写入前拷贝新对象。但是共享型也有个麻烦,那就是循环计数引用的问题。比如 A 指向 B, B 指向 A, 你想释放A,B还有一个计数在那里,所以你不能释放, 你想释放B也是同样的道理。 但是循环引用并不多见,vb 就是无视这个问题,也一样没见有多少人发觉是个问题。所以实际编码中,绝少出现。 但是为了杜绝一切可能,我们只好认真研究解决的方法。循环引用为何少发生,那是因为循环引用发生的条件很苛刻:首先,A,B需要是一个非普通类型对象,他们的成员有智能指针,然后指向对方类型。 也就是说,发生是依赖对象设计的,很少有这种对象设计,所以也就很少发生。要解决这个问题,我们可以防止这样的对象设计,但是免不了的时候,首先应该清楚有多少约束条件,知道得越多,就越容易找到突破口。比如这种情况只会出现在后期绑定(至少其中一个节点)上,在创建A就绑定B,创建B就绑定A,这是不可能成立的。

第六,指向栈中的对象,是危险的,栈有自己独特的释放规律。因此必须保证智能指针不指向栈中的对象。当然我想这是没有办法的,这是客户的任务,而不是设计者能办到的。也就是说存在这种循环引用的对象,应该只生存在堆中。因为如此,又必须由在栈中的智能指针来管理他们,因为你用普通指针,直接删除某个对象,都是破坏了整个对象循环结构,后果是严重的。 栈中的智能指针决定了这个对象循环的生命周期,如果没有栈中的指针,整个对象循环就应该析构。设计者可以想办法统计这个数据,来完成对象的释放。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值