QT5开发||07、QT5常见类(2)—容器类

摘要

在Qt库中为我们提供了一系列的基于模板的容器类。这些类可以被用来存储特定类型的项。这些容器类都是隐式共享的,可重入的,并且在速度上进行了优化,内存占用少,内联代码扩展少,从而可以产生更小的可执行文件。此外,当他们被用作只读容器时,还是线程安全的。

一、常见容器类

在开发一个较高性能需求的应用程序时,程序员会比较关注这些容器类的运
行效率,表2.1列出了QList、QLinkedList和QVector容器 的时间复杂度比较。

容器类 查找 插入 头部添加 尾部添加
QList O(1) O(n) Amort.O(1) Amort.O(1)
QLinkedList O(n) O(1) O(1) O(1)
QVector O(1) O(n) O(n) Amort.O(1)

二、QList类、 QLinkedList 类和QVector类

1、QList类

QList是迄今为止最常用的容器类,它存储给定数据类型T的一列数值。

QList不仅提供了可以在列表进行追加的QList::append()和list::prepend()函数,还提供了在列表中间完成插入操作的函数QList:insert()。

QList维护了一个指针数组,该数组存储的指针指向QList存储的列表项的内容。

对于不同的数据类型,QList采取不同的存储策略,存储策略有以下几种。

(1)如果T是一个指针类型或指针大小的基本类型(即该基本类型占有的字节数和指针类型占有的字节数相同),QList 会将数值直接存储

在它的数组中。

(2)如果QList存储对象的指针,则该指针指向实际存储的对象。

相关例子:

#include <QDebug> 
int main(int argc,char *argv[])
{
    
    
    QList<QString>list;
    {
    
    
        QString str("This is a test string");
        list<<str;
    }
    qDebug()<<list[0]<<"How are you!";
    return 0;
}

2. QLinkedList类

QLinkedList是一个链式列表,它以非连续的内存块保存数据。

QLinkedList不能使用下标,只能使用迭代器访问它的数据项。

3. QVector 类

QVector在相邻的内存中存储给定数据类型T的一组数值。

QVector既可以使用下标访问数据项,也可以使用迭代器访问数据项。

4. Java风格迭代器遍历容器

Java风格的迭代器是Qt 4新加入的一个功能。

对于每一个容器类,Qt都提供了两种类型的Java风格迭代器数据类型,即只读访问和读写访问,其分类见下表。

容器类 只读迭代器类 读写迭代器类
QList,QQueue QListIterator QMutableListIterator
QLinkedList QLinkedListIterator QMutableLinkedListIterator
Qvector,QStack QVectorIterator QMutableVectorIterator

5. STL风格迭代器遍历容器

对于每一个容器类,Qt都提供了两种类型的STL风格迭代器数据类型:一种提供只读访问;另- -种提供读写访问。

三、QMap类和QHash类

QMap类和QHash类具有非常类似的功能,它们的差别仅在于:

●QHash具有比QMap更快的查找速度;

●QHash以任意的顺序存储数据项,而QMap总是按照键Key顺序存储数据;

●QHash的键类型Key必须提供operator==()和一个全局的qHash(Key)函数,

而QMap的键类型Key必须提供operator<()函数。

二者的时间复杂度比较见下表。

容器类 键查找 插入
平均 最坏
QMap Olog(n) Olog(n)
QHash Amort.O(1) O(n)

1. QMap类

QMap<Key,T>提供了一个从类型为Key的键到类型为T的值的映射。

2. QHash类

QHash<Key,T>具有与QMap几乎完全相同的API。QHash维护着一张哈希表(HashTable),哈希表的大小与QHash的数据项的数目相适应。

3. Java风格迭代器遍历容器

对于每一个容器类,Qt都提供了两种类型的Java风格迭代器数据类型:一种提供只读访问;另一种提供读写访问。

下面的例子完成了QMap中的插入、遍历和修改。

#include <QDebug>
int main(int argc,char *argv[])
{
    
    
    QMap<QString,QString>map;
    map.insert("beijing","111");
    map.insert("shanghai","021");
    map.insert("nanjingjing","025");
    QMaplterator<QString,QString>i(map);
    for(;i.hasNext();)
            qDebug()<<" "<<i.key()<<" "<<i.next().value();
    QMutableMaplterator<QString,QString>mi(map);
    if(mifindNex(111"))
        mi.setValue("010");

    QMaplterator<QString,QString> modi(map); 
    qDebug()<<" ";
    for(;modi.hasNext();)
            qDebug()<<" "<<modi.key()<<" "<<modi.next().value();
    return 0;
}

四、QVariant类

1、QVariant类及QVariant与自定义数据类型转换的方法

这个类型相当于是Java里面的Object,它把绝大多数Qt提供的数据类型都封装起来,起到一个数据类型“擦除”的作用。比如我们的 table

单元格可以是string,也可以是int,也可以是一个颜色值,那么这么多类型怎么返回呢?于是,Qt提供了这个QVariant类型,你可以把这

很多类型都存放进去,到需要使用的时候使用一系列的to函数取出来即可。

比如你把int包装成一个QVariant,使用的时候要用 QVariant::toInt()重新取出来。这里需要注意的是,QVariant类型的放入和取出必须是

相对应的,你放入一个int就必须按int取出,不能用toString(), Qt不会帮你自动转换。数据核心无非就是一个 union,和一个标记类型的

type:传递的是整数 123,那么它union存储整数123,同时type标志Int;如果传递字符串,union存储字符串的指针,同时type标志

QString。

QVariant 属于 Qt 的Core模块,属于Qt的底层核心之一,ActiveQt、QtScript、QtDeclarative等都严重依赖于QVariant。

2、QVariant 可以保存很多Qt的数据类型

QVariant包括QBrush、QColor、QCursor、QDateTime、QFont、QKeySequence、 QPalette、QPen、QPixmap、QPoint、QRect、

QRegion、QSize和QString,并且还有C++基本类型,如 int、float等。QVariant还能保存很多集合类型,

如QMap<QSTRING, QVariant>, QStringList和QList。item view classes,数据库模块和QSettings都大量使用了QVariant类,,以方便

我们读写数据。

3、QVariant也可以进行嵌套存储,例如:

QMap<QString, QVariant> pearMap;   
pearMap["Standard"] = 1.95;   
pearMap["Organic"] = 2.25;   

QMap<QString, QVariant> fruitMap;   
fruitMap["Orange"] = 2.10;   
fruitMap["Pineapple"] = 3.85;   
fruitMap["Pear"] = pearMap;

QVariant被用于构建Qt Meta-Object,因此是QtCore的一部分。当然,我们也可以在GUI模块中使用,例如:

QIcon icon("open.png");   
QVariant variant = icon;   
// other function   
QIcon icon = variant.value<QIcon>();

我们使用了value()模版函数,获取存储在QVariant中的数据。这种函数在非GUI数据中同样适用,但是,在非GUI模块中,我们通常使用

toInt()这样的一系列函数,如toString()等。

至此,QT常见容器类就介绍完毕了!

猜你喜欢

转载自blog.csdn.net/weixin_43335226/article/details/106982096
Qt5