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