qlist的遍历_QT 容器及遍历

这篇博客介绍了QT容器的遍历方式,包括STL风格的遍历器、隐式数据共享的使用以及foreach循环。强调了使用at()而非[]操作符进行只读访问以优化性能,并讨论了QMap和QHash的插入、遍历以及如何通过不同类型的迭代器进行键值对的访问和修改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

QT容器遍历分为Java和STL遍历

STL风格遍历器的语法类似于使用指针对数组的操作。我们可以使用++和--运算符使遍历器移动到下一位置,遍历器的返回值是指向这个元素的指针。例如QVector的iterator返回值是 T *类型,而const_iterator返回值是 const T * 类型(数据为常量,返回值不能修改)。

一个典型的使用STL风格遍历器的代码是:

QList::iterator i = list.begin();

while (i != list.end()) {

*i = qAbs(*i);

++i;

}

对于某些返回容器的函数而言,如果需要使用STL风格的遍历器,我们需要建立一个返回值的拷贝,然后再使用遍历器进行遍历。如下面的代码所示:

QList list = splitter->sizes();

QList::const_iterator i = list.begin();

while (i != list.end()) {

doSomething(*i);

++i;

}

在C++中,很多人都会说,要避免这么写,因为最后一个return语句会进行临时对象的拷贝工作。如果这个对象很大,这个操作会很昂贵。所以,资深的C++高手们都会有一个STL风格的写法:

void sineTable(std::vector &vect)

{

vect.resize(360);

for (int i = 0; i < 360; ++i)

vect[i] = std::sin(i / (2 * M_PI));

}

// call

QVector v;

sineTable(v);

这种写法通过传入一个引用避免了拷贝工作。但是这种写法就不那么自然了。而隐式数据共享的使用让我们能够放心的按照第一种写法书写,而不必担心性能问题。

Qt所有容器类以及其他一些类都使用了隐式数据共享技术,这些类包括QByteArray, QBrush, QFont, QImage, QPixmap和QString。这使得这些类在参数和返回值中使用传值方式相当高效。

不过,为了正确使用隐式数据共享,我们需要建立一个良好的编程习惯。这其中之一就是,对list或者vector使用at()函数而不是[]操作符进行只读访问。原因是[]操作符既可以是左值又可以是右值,这让Qt容器很难判断到底是左值还是右值,而at()函数是不能作为左值的,因此可以进行隐式数据共享。另外一点是,对于begin(),end()以及其他一些非const容器,在数据改变时Qt会进行深复制。为了避免这一点,要尽可能使用const_iterator, constBegin()和constEnd().

最后,Qt提供了一种不使用遍历器进行遍历的方法:foreach循环。这实际上是一个宏,使用代码如下所示:

QLinkedList list;

Movie movie;

...

foreach (movie, list) {

if (movie.title() == "Citizen Kane") {

std::cout << "Found Citizen Kane" << std::endl;

break;

}

}

Qt容器类之关联存储容器

Qt提供两种关联容器类型:QMap和QHash。

QMap是一种键-值对的数据结构,它实际上使用跳表skip-list实现,按照K进行升序的方式进行存储。使用QMap的insert()函数可以向QMap中插入数据,典型的代码如下:

QMap map;

map.insert("eins", 1);

map.insert("sieben", 7);

map.insert("dreiundzwanzig", 23);

同样,QMap也重载了[]运算符,你可以按照数组的复制方式进行使用:

map["eins"] = 1;

map["sieben"] = 7;

map["dreiundzwanzig"] = 23;

int val = map.value("dreiundzwanzig");

遍历关联存储容器的最简单的办法是使用Java风格的遍历器。因为Java风格的遍历器的next()和previous()函数可以返回一个键-值对,而不仅仅是值,例如:

QMap map;

...

int sum = 0;

QMapIterator i(map);

while (i.hasNext())

sum += i.next().value();

如果我们并不需要访问键-值对,可以直接忽略next()和previous()函数的返回值,而是调用key()和value()函数即可,如:

QMapIterator i(map);

while (i.hasNext()) {

i.next();

if (i.value() > largestValue) {

largestKey = i.key();

largestValue = i.value();

}

}

Mutable遍历器则可以修改key对应的值:

QMutableMapIterator i(map);

while (i.hasNext()) {

i.next();

if (i.value() < 0.0)

i.setValue(-i.value());

}

如果是STL风格的遍历器,则可以使用它的key()和value()函数。而对于foreach循环,我们就需要分别对key和value进行循环了:

QMultiMap map;

...

foreach (QString key, map.keys()) {

foreach (int value, map.values(key)) {

doSomething(key, value);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值