Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1405469
  • 博文数量: 120
  • 博客积分: 182
  • 博客等级: 入伍新兵
  • 技术积分: 2278
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-19 16:31
文章分类

全部博文(120)

文章存档

2015年(12)

2014年(13)

2013年(40)

2012年(55)

分类: C/C++

2013-10-23 20:42:36

     之前写过一篇学习有关隐式共享的文章,那只是比较粗浅的学习,只有大致的了解,其实当时自己也不是特别懂,不知道会在哪里用到呢?后来查别的资料涉及到了隐式共享,觉得很好的,所以再次记录下来,作为学习笔记吧。
       其实,在使用Qt容器类的时候会可能用到隐式共享机制(implicit sharing),也叫做copy on write。顾名思义,就是说,在内容有变动的情况下才对容器中的数据结构做复制,否则仅做共享。比如:
  1. QList<QString> list1;
  2. list1 << "helianthus";
  3. QList<QString> list2 = list1;
  4.     
  5. cout << &list1[0] << endl;
  6. cout << &list2[0] << endl;
在这个例子中使用了[]运算子,list1和list2中的数据结构经过了复制,所以并不是共享的。因此最后显示的两个记忆体位置并不相同,但是使用了at()时的情况是一样的:
  1. QList<QString> list1;
  2. list1 << "x";
  3. QList<QString> list2 = list1;
  4. //QList::at(int i) const:Returns the item at index position i in the list. i must be a 
  5. //valid index position in the list (i.e., 0 <= i < size())   
  6. cout << &(list1.at(0)) << endl; 
  7. cout << &(list2.at(0)) < < endl;
所以,在只读的情况下,使用at()方法要比使用[]运算子效率高,因为省去了数据结构的复制成本。
      隐式共享之所以称为copy on write,也就是说只要容器中的数据结构内容发生了变化就不再共享,而要复制。就上一个例子而言,如果对list2做了修改,比如:
  1. list2 << "linux";
那么:
  1. cout << &(list1.at(0)) << endl;
  2. cout << &(list2.at(0)) << endl;
此时list1和list2显示的记忆体位置就是不同的。
再比如:
  1. QList<int> function() {
  2.     QList<int> list;
  3.     // ...blah..blah
  4.     cout << &list << endl;
  5.     return list;
  6. }
然后,就可以利用这个函数实现数据共享,又不会数据结构复制:
  1. QList<int> retval= function();
  2. cout << &retval << endl;
在上面这个代码片段中,function()中的list位置和接收function中的list的retval位置是相同的。总的来说,QT中所有的容器类都支持隐式共享;此外,QByteArray,QBrush,QPen,QPalette,QBitmap,QImage,QPixmap,QCursor,QDir,QFont和QVariant等也都只是隐式共享机制。
      而无论是Java风格还是STL风格的迭代器,使用只读迭代器时,背后也都使用到了隐式共享机制,以增加读取的效率。
阅读(6842) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~