设为首页 加入收藏

TOP

条款14:缓式优化,之二:(2)
2013-10-07 14:02:44 来源: 作者: 【 】 浏览:58
Tags:条款 优化 之二

条款14:缓式优化,之二:(2)

在析构函数中,我们要记得对引用计数进行管理,因为可能有其他的String对象正在共享相同的StringBuf实体。如果其他String对象还在使用这个StringBuf,我们就无须理会它,只用递减引用计数以表明我们不再需要它,然后退出。但如果我们是StringBuf的最后一个客户,我们就要清除它:

  1. String::~String()  
  2. {  
  3. if ( --data_->refs < 1 )       // 最后一个  
  4. {  
  5. delete data_;                   // ...关灯(删除缓冲区)  
  6. }  

仅有的另外一个需要修改引用计数的地方是复制构造函数,在那儿,为了实现"缓式复制"语义,我们只需简单地指向另一个String已有的StringBuf,并递增计数以记录我们的存在。这是一种"浅复制"。只是在需要对"共享这个缓冲区的其中一个字符串"进行修改时,我们才会分离这个实体(即,执行"深复制"):

  1. String::String( const String& other )  
  2. : data_(other.data_)  
  3. {  
  4. ++data_->refs;  

为了提高代码的清晰性,我还另外实现了一个辅助函数AboutToModify();因为除了Append(),其他修改操作函数(mutators)也需要用到它。AboutToModify()确保我们拥有一个非共享的内部缓冲区复制--如果在此之前没有执行深复制,现在就会执行。为了方便,AboutToModify()还提供了一个参数,表示欲分配缓冲区的最小值,这样,我们就不会不必要地得到一个已经满载的字符串复制,然后又立即转过头去执行第二次分配以获得更大的空间。

  1.     void String::AboutToModify( size_t n )  
  2.     {  
  3. if( data_->refs > 1 )  
  4. {  
  5.           auto_ptr<StringBuf> newdata( new StringBuf );  
  6.           newdata->Reserve ( max( data_->len, n ) );  
  7.           copy( data_->buf, data_->buf+data_->used,  
  8. newdata.get()->buf );  
  9.           newdata->used = data_->used;  
  10.  
  11. --data_->refs;              // 现在,所有实际工作已经完成,  
  12. data_ = Newdata.release();  // 所以,获得拥有权  
  13. }  
  14. else  
  15. {  
  16. data_->Reserve( n );  
  17. }  

既然其他部分已经就绪,Append()就很简单了。和前面一样,它只是宣告将要修改字符串,从而保证物理字符串缓冲区不被共享,而且其大小足以容纳另外一个字符。然后,它继续前进,执行修改操作:

  1. void String::Append( char c ) {  
  2. AboutToModify( data_->used+1 );  
  3. data_->buf_[data_->used++] = c;  
  4. }  

所有的工作就这么多。下一步,我们将使接口更丰富一些,并看看这会带来什么变化。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇实例021 在VC中如何进行远程调试 下一篇条款14:缓式优化,之二:(1)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: