建立网站项目计划书模板,泰兴市网站建设,深圳网站建设套餐,如何在建设部网站查询获奖情况迭代器(iterator)为访问容器类里的数据项提供了统一的方法#xff0c;Qt有两种迭代器类#xff1a;Java类型的迭代器和STL类型的迭代器。 Java类型的迭代器更易于使用#xff0c;且提供一些高级功能#xff0c;而STL类型的迭代器效率更高。 Qt还提供一个关键字foreach… 迭代器(iterator)为访问容器类里的数据项提供了统一的方法Qt有两种迭代器类Java类型的迭代器和STL类型的迭代器。 Java类型的迭代器更易于使用且提供一些高级功能而STL类型的迭代器效率更高。 Qt还提供一个关键字foreach实际是QtGlobal里定义的一个宏用于方便地访问容器里所有数据项。 1.JAVA类型迭代器 1.1 JAVA类型迭代器总表 对于每个容器类有两个Java类型迭代器一个用于只读操作一个用于读写操作。 Map和QHash等关联容器类的迭代器用法相同QList和QLinkedList、QSet等容器类的用 法相同所以下面只以QMap和QList为例介绍迭代器的用法。Java类型的迭代器如表3-3所示。 Java类型迭代器的指针不是指向一个数据项而是在数据项之间迭代器指针位置示意图如图所示。 图1-1 JAVA类型迭代器位置示意图 1.2 顺序容器类的迭代器的使用 1.2.1 Java类型QList容器类迭代器 1QListIterator常用函数 QListIterator用于移动指针和读取数据的函数见表3-4。 2正向遍历QListQString容器所有数据 QListQString容器对象list作为参数传递给QListlteratorQString迭代器i的构造函数i 用于对list作只读遍历。起始时刻迭代器指针在容器第一个数据项的前面图1-1中数据项A” 的前面调用hasNext()判断在迭代器指针后面是否还有数据项如果有就调用next()跳过一个 数据项并且next()函数返回跳过去的那个数据项。 QListQStringlist; listABCD; QListIteratorQStringi(list) while(i.hasNext()) qDebug()i.next() 2反向遍历QListQString容器所有数据 QListIteratorQStringi(list) i.toBack(); while(i.hasprevious()) qDebug()i.previous; 代码和正序遍历是对称的我们调用toBack()将迭代器移到最后一项后面的位置。下图描述了在一 个迭代器上调用next()和previous()函数的效果 3QMutableListIterator遍历修改容器数据 QListintlist; list12345; QMutableListIteratorinti(list); while(i.hasNext()){ if(i.next()%2 0) i.remove();//remove()函数移除next()函数刚刚跳过的一个数据项不会使迭代器失效。 if(i.next() 128) i.setValue(128);//setValue()函数可以修改刚刚跳过去的数据项的值 } 1.3 关联容器类的迭代器的使用 1.3.1 Java类型QMap容器类迭代器 对于关联容器类QMapKeyT使用QMapIterator和QMutableMapIterator迭代器类它们具 有表3-4所示的所有函数主要是增加了 key()和value()函数用于获取刚刚跳过的数据项的键和值。 例如下面的代码将删除键城市名称里以“City”结尾的数据项。 QMapQString,QStringmap; map.insert(Paris,France); map.insert(New York,USA); maP.insert(Mexico City,USA); map·insert(Moscow,Russia); ...... QMutab1eMapIteratorQString,QStringi(map); while(i.hasNext()){ if(i.ne×().key().endsWith(City)) i.remove(); } 如果是在多值容器里遍历可以用 findNext()或findPrevious()查找下一个或上一个值如下面 的代码将删除上一示例代码中map里值为USA”的所有数据项。 QMutableMapIteratorQString,QStringi(map); while(i.findNext(USA)) i.remove(); 2.STL类型迭代器 2.1 STL类型迭代器总表 STL迭代器与Qt和STL的原生算法兼容并且进行了速度优化。具体类型见表3-5。 对于每一个容器类都有两个STL类型迭代器一个用于只读访问一个用于读写访问。无需修改数据时一定使用只读迭代器因为它们速度更快。 注意在定义只读迭代器和读写迭代器时的区别它们使用了不同的关键字const_iterator定义只读迭代器iterator定义读写迭代器。此外还可以使用const_reverse_iterator和reverse_iterator定义相应的反向迭代器。 STL类型的迭代器是数组的指针所以“”运算符使迭代器指向下一个数据项“*”运算符返回数据项内容。与Java类型的迭代器不同STL迭代器直接指向数据项STL迭代器指向位置示意图如图2-1所示。 图2-1 STL类型迭代器位置示意图 begin()函数使迭代器指向容器的第一个数据项end()函数使迭代器指向一个虚拟的表示结尾的数据项end()表示的数据项是无效的一般用作循环结束条件。下面仍然以QList和QMap为例说明sTL迭代器的用法其他容器类迭代器的用法类似。 2.2 顺序容器类的迭代器的使用 2.2.1 STL类型QList容器类迭代器 (1)正向只读迭代器 QListQStringlist; listABCD; QListQString::const_iterator i; for(i list.constBegin();i ! list.constEnd();i) qDebug()*i; 2反向读写迭代器 constBegin()和constEnd()是用于只读迭代器的表示起始和结束位置。 若使用反向读写迭代器并将上面示例代码中list的数据项都改为小写代码如下 QLIstanbulQString::reverse_iterator i; for(i list.rbegin();i list.rend();i) *i i-toLower();//修改数据 2.3 关联容器类的迭代器的使用 2.3.1 STL类型QMap容器类迭代器 对于关联容器类QMap和QHash迭代器的“*”操作符返回数据项的值。如果想返回键使用key()函数。对应的用value()函数返回一个项的值。 例如下面的代码将QMapint,intmap中所有项的键和值输出。 QMapint,intmap ...... QMapint,int::const_iterator; for(i list.constBegin();i ! list.constEnd();i) qDebug()i.key():i.value(); Qt API包含很多返回值为QList或QStringList的函数要遍历这些返回的容器必须先复制。由于Qt使用了隐式共享这样的复制并无多大开销。例如下面的代码是正确的。 const QListintsizes splitter-sizes(); QListint::const_iterator i; for(i sizes.begin();i !sizes.end();i) qDebug()*i; 提示隐式共享Implicit Sharing是对象的管理方法。一个对象被隐式共享只是传递该对象的一个指针给使用者而不实际复制对象数据只有在使用者修改数据时才实质复制共享对象给使用者。如在上面的代码中splitter-sizes()返回的是一个QListint列表对象sizes,但是实际上代码并不将splitter-sizes()表示的列表内容完全复制给变量sizes,只是传递给它一个指针。只有当sizes发生数据修改时才会将共享对象的数据复制给sizes,这样避免了不必要的复制减少了资源占用。 下面的代码是错误的。对于STL类型的迭代器隐式共享还涉及另外一个问题即当有一个迭代器在操作一个容器变量时不要去复制这个容器变量。 QListint::const_iterator i; for(i splitter-sizes().begin();i !splitter-sizes().end();i) qDebug()*i; 2.3.2 STL风格迭代器的API 下面的表概括了STL风格迭代器的API 表达式 用途 *i 返回当前项 i 将迭代器指向下一项 i n 迭代器向前移动n项 --i 将迭代器指向上一项 i - n 将迭代器你向后移动n项 i - j 返回迭代器i和j之间项的数目 3.foreach关键字 如果只是想遍历容器中所有的项可以使用foreach关键字。foreach是QtGlobal头文件中定义的一个宏。使用foreach的句法是 foreach(variablecontainer) 使用foreach的代码比使用迭代器更简洁。例如使用foreach遍历一的示例代码如下 QLinkedListQStringlist; ... QString str; foreachstr,list qDebug()str 用于迭代的变量也可以在foreach语句里定义foreach语句也可以使用花括号可以使用break 退出迭代示例代码如下 QLinkedListQStringlist; foreach(const QString str,list) { if(str.isEmpty()) break; qDebug()str } 对于QMap和QHashforeach会自动访问“键一一值”对里的值所以无需调用values()。如果需要访问键则可以调用keys()示例代码如下 QMapQString,intmap; ...... foreach(const QString str,map.keys()) qDebug()str:map.value(str); 对于多值映射可以使用两重foreach语句示例代码如下 QMultiMapQString,intmap; ... foreach(const QString str,map.uniqueKeys()) foreach(int i,map.values(str)) qDebug()str:i; 注意foreach关键字遍历一个容器变量是创建了容器的一个副本所以不能修改原来容器变量的数据项。