QT容器类(二) 之 Iterator

  • Post author:
  • Post category:其他


说明:

Qt支持两种风格的迭代器——Java-style和STL-style

Java-style的迭代器更容易使用,而STL-style的迭代器可以同Qt和STL中的算法联合使用,更为强大。

(一)Java-style Iterator

每个sequential容器类,都有两个Java-style的迭代器类型:只读迭代器和读写迭代器。

在使用Java-style的迭代器时,要清楚的第一件事情就是:迭代器并不直接指向容器中的元素,而是指向元素之前或之后的位置。迭代器被初始化时指向容器中第一个元素之前;若迭代器的右侧有元素存在,hasNext()函数返回true;next()函数返回位于迭代器右侧的元素,并将迭代器向右方移动一个元素的位置;hasPrevious()和previous()函数执行反方向的操作。


remove()函数总是删除最近一次被跳过的那个元素。

setValue()函数总是对最近一次被跳过的那个元素执行更新操作

insert()函数在迭代器当前指向的位置处插入新元素,并将迭代器指向新元素及其后续元素之间的位置。

(二)STL-style Iterator

每个sequential容器类,都有两个STL-style的迭代器类型:Container<T>::iterator和Container<T>::const_iterator。

容器的begin()函数返回一个指向容器中头部元素的iterator,而end()返回指向容器中尾部元素之后位置的iterator;

在容器为空时,begin()和end()的结果相同。


通常通过调用isEmpty()来检查容器是否为空,而不是通过比较begin()和end()的结果。

可以对STL-style的iterator使用+、-、*这三个运算符,类似于指针的用法。

某些Qt函数的返回值是容器类;如果需要使用STL-style的迭代器来对这样的返回值进行遍历,必须保存返回值的一个副本,并在副本上完成遍历,否则会可能会导致所谓的”dangling iterator”。

注意,若使用java-style的只读迭代器,在这种情况下会隐式的完成复制的工作,保证迭代器总是在副本上进行遍历操作。

implicit sharing(copy on write)

Qt中的implicit sharing机制的美妙之处在于它鼓励程序员在返回对象时采用传值这种简明的方式而不是引用或指针。

STL与此相反,鼓励程序员使用non-const引用来传递vector以避免将函数返回值的复制开销。

Qt中所有的容器都采用了implicit sharing机制;此外很多其他类QByteArray,QBrush,QFont,QImage,QString也采用了该机制——这保证这些类在以传值方式进行传递时有很高的效率,无论是作为参数还是函数返回值。

在Qt提供的implicit sharing机制下,对vector或list执行只读操作时,采用at()而不是[]运算符是一个更好的选择。

类似的,尽可能的使用constBegin()和constEnd()以避免不必要的拷贝操作。

(三)foreach syntax

foreach在进入循环体时自动复制容器的副本并在此副本上进行迭代,因此如果迭代过程中有通过迭代器对容器的修改操作的话,并不会影响循环的进行,循环结束后容器的内容也不会发生变化。

当然,如果在foreach循环中直接使用[]运算符对容器进行写操作的话,容器内容自然会发生变化。

foreach中支持break和continue语句



版权声明:本文为hustyangju原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。