Skip to main content
 首页 » 编程设计

C++ 容器类教程

2022年07月19日148exmyth

本文我们讨论Qt5 容器类,主要包括QVector, QList, QStringList, QSet, QMap类。容器类是通用类型,用于存储特定类型的对象集合,C++提供了STL,在Qt中我们可以使用Qt容器或STL容器。

概述

Qt主要提供了两种类型的容器:顺序和关联。顺序类容器一个接着一个地存储对象,而关联容器按照键值对方式存储对象。QList, QVector, QLinkedList是顺序类,QMap 和 QHash 是关联类。

我们的示例主要为命令行程序,不需要Qt GUI模块,因此在项目文件中增加 QT -= gui 去掉GUI模块依赖。

Qt5 QVector

QVector 是模板类,提供了动态数组功能。它用连续内存地址存储对象,并提供索引方式快速访问元素。对于非常大的向量,插入操作非常慢,建议使用QList容器代替。

#include <QVector> 
#include <QTextStream> 
 
int main(void) { 
 
    QTextStream out(stdout); 
 
    // 声明int类型向量,并初始化 
    QVector<int> vals = {1, 2, 3, 4, 5}; 
 
    // size方法输出向量元素数量大小 
    out << "The size of the vector is: " << vals.size() << endl; 
 
     
    out << "The first item is: " << vals.first() << endl; 
    out << "The last item is: " << vals.last() << endl; 
 
    // 追加元素 
    vals.append(6); 
    // 前面插入元素 
    vals.prepend(0); 
 
    out << "Elements: "; 
 
    // 遍历元素 
    for (int val : vals) { 
        out << val << " "; 
    } 
 
    out << endl; 
 
    return 0; 
} 

代码几乎是自解释的,部分语句增加了注释。运行输出结果:

The size of the vector is: 5 
The first item is: 1 
The last item is: 5 
Elements: 0 1 2 3 4 5 6 

Qt5 QList

QList 是列表元素的容器类。与QVector类似,它存储对象列表,基于索引方式快速访问,而且插入、删除速度也很快,是最常用的容器。

// mylist.cpp 
#include <QTextStream> 
#include <QList> 
#include <algorithm> 
 
int main(void) { 
 
    QTextStream out(stdout); 
 
    // 创建字符串列表,并初始化 
    QList<QString> authors = {"Balzac", "Tolstoy", "Gulbranssen", "London"}; 
 
    通过索引遍历 
    for (int i=0; i < authors.size(); ++i) { 
        out << authors.at(i) << endl; 
    } 
 
    authors << "Galsworthy" << "Sienkiewicz"; 
 
    out << "***********************" << endl; 
 
    // 列表排序 
    std::sort(authors.begin(), authors.end()); 
 
    out << "Sorted:" << endl; 
    for (QString author : authors) { 
        out << author << endl; 
    } 
 
    return 0; 
} 

运行输出结果:

Balzac 
Tolstoy 
Gulbranssen 
London 
*********************** 
Sorted: 
Balzac 
Galsworthy 
Gulbranssen 
London 
Sienkiewicz 
Tolstoy 

QStringList

QStringList是非常方便的字符串列表容器类,可以基于索引快速访问,并且插入删除速度也很快。

#include <QTextStream> 
#include <QList> 
#include <QStringList> 
 
int main(void) { 
 
    QTextStream out(stdout); 
 
    // 定义字符串 
    QString string = "coin, book, cup, pencil, clock, bookmark"; 
 
    // 通过split方法生成QStringList对象 
    QStringList items = string.split(","); 
 
    // 定义迭代器 
    QStringListIterator it(items); 
 
    while (it.hasNext()) { 
        out << it.next().trimmed() << endl; 
    } 
 
    return 0; 
} 

输出结果:

coin 
book 
cup 
pencil 
clock 
bookmark 

Qt5 QSet

QSet 提供了具备快速查找功能的不重复值集合。这些值以无序方式存储。下面示例存储颜色,如果有重复值会自动去重。

#include <QSet> 
#include <QList> 
#include <QTextStream> 
#include <algorithm> 
 
int main(void) { 
 
    QTextStream out(stdout); 
 
    // 定义两个Set集合 
    QSet<QString> cols1 = {"yellow", "red", "blue"}; 
    QSet<QString> cols2 = {"blue", "pink", "orange"}; 
 
    // 输出元素数量 
    out << "There are " << cols1.size() << " values in the set" << endl; 
 
    cols1.insert("brown"); 
 
    out << "There are " << cols1.size() << " values in the set" << endl; 
 
    // 连个集合取并集 
    cols1.unite(cols2); 
 
    out << "There are " << cols1.size() << " values in the set" << endl; 
 
    for (QString val : cols1) { 
        out << val << endl; 
    } 
 
    // 排序 
    QList<QString> lcols = cols1.values(); 
    std::sort(lcols.begin(), lcols.end()); 
 
    out << "*********************" << endl; 
    out << "Sorted:" << endl; 
 
    for (QString val : lcols) { 
        out << val << endl; 
    } 
 
   return 0; 
} 

输出结果:

There are 3 values in the set 
There are 4 values in the set 
There are 6 values in the set 
pink 
orange 
brown 
blue 
yellow 
red 
********************* 
Sorted: 
blue 
brown 
orange 
pink 
red 
yellow 

Qt5 QMap

QMap 是关联数组(字典),用于存储键值对,通过键可以快速查找值。下面示例映射字符串至整数值:

#include <QTextStream> 
#include <QMap> 
 
int main(void) { 
 
    QTextStream out(stdout); 
    // 创建Map包括两个键值对 
    QMap<QString, int> items = { {"coins", 5}, {"books", 3} }; 
 
    // 插入键值对 
    items.insert("bottles", 7); 
 
    QList<int> values = items.values(); 
 
    out << "\nValues:" << endl; 
 
    for (int val : values) { 
        out << val << endl; 
    } 
 
    // 获取所有键集合 
    QList<QString> keys = items.keys(); 
 
    out << "\nKeys:" << endl; 
    for (QString key : keys) { 
        out << key << endl; 
    } 
 
    // 获取迭代器 
    QMapIterator<QString, int> it(items); 
 
    out << "\nPairs:" << endl; 
 
    while (it.hasNext()) { 
        it.next(); 
        out << it.key() << ": " << it.value() << endl; 
    } 
 
    return 0; 
} 

输出结果:

Values: 
3 
7 
5 
 
Keys: 
books 
bottles 
coins 
 
Pairs: 
books: 3 
bottles: 7 
coins: 5 

自定义类排序

下面示例展示如何对自定义类QList进行排序,首先定义Book类头文件:

// book.h 
class Book { 
 
    public: 
        Book(QString, QString); 
        QString getAuthor() const; 
        QString getTitle() const; 
 
    private: 
        QString author; 
        QString title; 
}; 

Book类的实现类:

// sortcustomclass.cpp 
 
#include <QTextStream> 
#include <QList> 
#include <algorithm> 
#include "book.h" 
 
// 创建排序类,依据标题排序 
bool compareByTitle(const Book &b1, const Book &b2) { 
  return b1.getTitle() < b2.getTitle(); 
} 
 
int main(void) { 
 
    QTextStream out(stdout); 
 
    // 定义Book对象List集合 
    QList<Book> books = { 
        Book("Jack London", "The Call of the Wild"), 
        Book("Honoré de Balzac", "Father Goriot"), 
        Book("Leo Tolstoy", "War and Peace"), 
        Book("Gustave Flaubert", "Sentimental education"), 
        Book("Guy de Maupassant", "Une vie"), 
        Book("William Shakespeare", "Hamlet") 
    }; 
 
    // 按照自定义排序方法进行排序 
    std::sort(books.begin(), books.end(), compareByTitle); 
 
    for (Book book : books) { 
        out << book.getAuthor() << ": " << book.getTitle() << endl; 
    } 
 
    return 0; 
} 

输出结果:

Honoré de Balzac: Father Goriot 
William Shakespeare: Hamlet 
Gustave Flaubert: Sentimental education 
Jack London: The Call of the Wild 
Guy de Maupassant: Une vie 
Leo Tolstoy: War and Peace 

本文参考链接:https://blog.csdn.net/neweastsun/article/details/123809267