设为首页 加入收藏

TOP

Qt中的容器类(一)
2014-11-24 13:55:59 来源: 作者: 【 】 浏览:5
Tags:容器

Qt提供了两种类型的容器类:序列容器和关联容器。例如QVector,QLinkedListQList属于序列容器,而QMapQHash属于关联容器。


Qt提供了通用的算法,对这些容器类执行一些操作,如qSort()对一个序列容器进行排序,而qBinaryFind()在一个排过序的序列容器内执行二叉树查找。


序列容器


QVector是一个类数组的数据结构,与C++中普通的数组不同之外是:一个向量知道本身的大小并可被重置大小。将一个向量的末尾添加一个新的项相当有效,而往其前面或中间插入一个项则代价比较昂贵。


用法:


在提前知道大小的情况下:


QVectorvect(3);


vect[0]= 1.0;


vect[1]= 0.540302;


vect[2]= -0.416147;


在大小不可知的情况下:


QVectorvect;


vect.append(1.0);


vect.append(0.540302);


vect.append(-0.416147);



vect<< 1.0 << 0.540302 << -0.416147;


遍历一个向量:


doublesum = 0.0;


for(int i = 0; i < vect.count(); ++i)


sum+= vect[i];


QLinkedList是一个链表数据结构,它不支持随机访问,但可以很高效的完成插入和删除操作。链表是通过迭代子来访问的。链表的使用如下所示:


QLinkedListlist;


list.append("Clash");


list.append("Ramones");


QLinkedList::iteratori = list.find("Ramones");


list.insert(i,"Tote Hosen");


QList结合了QVectorQLinkedList的优点,是一个“数组-链表”,它的接口是基于索引的,它是一个最合适的通用容器类。


QStackQQueue是两个更实用的子类。QStack在向量的基础上增加了push(),pop()top()方法,而QQueue在链表的基础上增加了enqueue(),dequeue()head()方法。


说明:对于所有的容器类,类型T可以是基本的数据类型,如整型或双精度型,指针类型或一个拥有默认构造函数,一个拷贝函数和一个赋值操作符的类,这些类包括QByteArray,QDateTime,QRegExp,QStringQVariant。从QObject类中继承的子类不能作为窗口类的项,因为它们的拷贝函数和赋值操作符被禁用了。


解决办法(Trick):将指向这些对象的指针作为容器类的项,而不是对象本身。


T也可以是一个容器类,但在写法上要注意:


QList> list;


如上,两个>之间一定要有空格,否则编译会将其解释为>>而导致出错。


容器的遍历——迭代器


Java风格的迭代器:只读和读写迭代器。只读迭代器类有QVectorIteratorQLinkedListIteratorQListItrator,相应的读写迭代器在名字中有个Mutable,QMutableVectorIterator


使用Java风格的迭代器时要注意,迭代子并不直接指向容器中的项,它们可定位在第一项之前,最后一项之后或两者之间,如下所示:


QListlist;


...QListIterator i(list);


while(i.hasNext()) {


do_something(i.next());


}


注:在Java风格的只读迭代器中,可以直接对容器进行操作,无需一份拷贝,这些细节已经由相应的类自动完成了,如


QListIteratori(splitter->sizes());


while(i.hasNext()) {


do_something(i.next());


}




STL风格的迭代器;


只读:QVector::iterator,读写: QVector::const_iterator


如:


QListlist = splitter->sizes();


QList::const_iteratori = list.begin();


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


do_something(*i);


++i;


}


注意,在STL风格下,我们只能对容器的拷贝进行迭代。


//错误写法:


while(i != splitter->sizes().end()) {


do_something(*i);


++i;


}




隐式共享


由于存在隐式共享,拷贝一个容器类代价并不高,与复制一个指针的代价差不多。仅当某个容器的拷贝内容发生变化时才进行真正的拷贝,有点像Linux中父过程与子进程之间的“写时复制”共享数据。隐式共享鼓励对象通过传值的方式返回。


Qt中所有的容器类以及许多其他的类都使用了隐式共享,包括QByteArray,Qbrush, AFont, QImage,QPixmapQString。这些类通过传值的方式传递时非常高效,不管是作为函数参数或是作为函数返回值。


隐式共享保证了数据只有被修改时才会进行真正的复制。所以在Qt中,尽管使用只读形式的接口。


关联容器


Qt提供了两个主要的关联容器类:QMapQHash


访问方式如下代码所示:



QMap map;


map.insert("eins",1);


map.insert("sieben",7);


map.insert("dreiundzwanzig",23);



map["eins"]= 1;


map["sieben"]= 7;


map["dreiundzwanzig"]= 23;





intval = map.value("dreiundzwanzig");



intseconds = map.value("delay", 30);带默认值。




QMultiMap是一种1对多的映射容器。


QHashQMap的接口类似,不过它是无序的,它也有一个变体QMultiHash




通用算法


包含了一些通用的全局模板函数,实现了操作于容器类数据的通用算法。


qFind(),qCopy(), qFill(), qSort()等。




类容器类


与容器类有许多共性的三个类是:QString, QByteArray, QVariant


QString的值是16Unicode值,包含ASCIILatin-1QString可认为是一个元素为QChar类型的向量,它可嵌入’\0’length()函数返回的值包含嵌入的’\0’QString支持++=连接字符串,也可以使用append()方式。也可以使用sprintf()方法连接不同的字符串,如:


str.sprintf("%s%.1f%%", "perfect competition", 100.0);


显示地将一个constchar*型字符串转换为QString类型的方法如下:


constchar* str = “This is a test”;


QStringqstr = (QString)str;


qstr= QStirng::fromAscii(str)qstr= QString::fromLatin1();


QString转变为constchar*型的步骤如下:


QString与中文显示问题


QString本身是支持中文显示的,它默认是支持unicode的。要使QString能正常地显示中文,必须传递合适的unicode。有两种方法:


如: w.setWindowTitle(QTextCodec::codecForName("gb2312")->to

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇procfs信息读取实现案例 下一篇Qt输入输出

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: