QVector

1. QVector 是什么?

QVector 是 Qt 框架提供的一个模板类,它是一个动态数组。你可以把它理解为 C++ 标准库中的 std::vector 的 Qt 版本。

核心特点:

  • 动态大小: 它可以在运行时动态地增加或减少其容量,你不需要在编译时指定固定的大小。

  • 连续存储: 它的元素在内存中是连续存储的。这意味着通过索引访问元素(例如 vector[5])的速度非常快,因为可以直接通过地址偏移来计算位置。

  • Qt 风格: 它提供了完整的 Qt 风格的 API,能与 Qt 的其他部分(如信号槽、foreach 宏、迭代器等)无缝集成。


2. 基本用法

2.1 包含头文件和创建对象

 包含头文件


#include <QVector>
创建对象
 //创建一个空的QVecotr,用于存储int类型的数据
 QVector<int> vec;

 //创建一个厨师大小为10的QVector,每个元素默认初始化为0
 QVector<int> vec2(10);

 //创建一个初始大小为5的QVector,每个元素都初始化为42
 QVector<int> vec3(5, 42);
 
 //使用初始化列表(C++11及以上)
 QVector<int> vec4 = { 1,2,3,4,5 };

2.2 添加元素

    QVector<QString> fruits;
    
    //1.append() 或push_back()  在末尾添加元素
    fruits.append("Apple");
    fruits.push_back("Banana");//与append()效果相同
    
    //2.prepend()或者push_front();//在开头添加元素
    fruits.prepend("Orange");

    //3.insert();  在指定位置插入元素
    fruits.insert(1, "Grape");//在索引1的位置,就是第二个插入"Grape"
    // 此时 fruits 的内容: ["Orange", "Grape", "Apple", "Banana"]

 


2.3 访问元素


重要: 确保索引在有效范围内 [0, size()-1],否则会导致未定义行为。

   QVector<QString> fruits = { "Apple","Banana","Orange" };

   //1.使用operator[] (不检查边界,速度更快)
   QString first = fruits[0];//"Apple"

   //2.使用at() (不检查边界)
   QString second = fruits.at(1);//结果:"Banana"
   //QString second1 = fruits.at(100);//会报异常

   //3.访问第一个和最后一个
   QString front = fruits.first();//结果:"Apple"
   QString back = fruits.last();//结果:"Orange"

   //4.修改元素
   fruits[0] = "Mango";// 现在第一个元素变成了 "Mango"

2.4 删除元素

 QVector<int> numbers = { 10,20,30,40,50,30 };

 //1. removeAt()  删除指定位置的元素
 numbers.removeAt(2);//删除索引为2的元素(30)
 // 现在 numbers: [10, 20, 40, 50, 30]

 //2.removeOne()删除第一个匹配到的值
 numbers.removeOne(30);
 // 现在 numbers: [10, 20, 40, 50]
 numbers.removeOne(25);


 //3.removeAll() 删除所有匹配的值
 numbers = { 10,20,30,40,50,30 };
 numbers.removeAll(30);//删除所有的30
 // 现在 numbers: [10, 20, 40, 50]


 // 4. removeFirst() / removeLast() / pop_front() / pop_back(): 删除首/尾元素
 numbers.removeFirst(); // 删除 10
 numbers.pop_back();    // 删除 50

 // 5. clear(): 清空整个 QVector
 numbers.clear();

2.5 获得QVecotr  数量

  //获得QVecotr  数量
  QVector<int> numbers = { 10,20,30,40,50,30 };
  int size = numbers.size();
 int size = vec.count();

 

2.6 查找和判断


    QVector<QString> vec = { "A","B","C","D" };
    
    //1.contains()  判断是否包含某个元素
    bool hasB = vec.contains("B");//结果:true
    bool hasE = vec.contains("E");//结果:false

    //2.indexOf();  查找元素的索引(从前往后)
    int index1 = vec.indexOf("C");//结果:2
    int index2 = vec.indexOf("X");//结果:-1  ,表示没找到

    //3.LastIndexof();  查找元素的索引(从后往前)
    vec.append("B");
    int lastIndex = vec.lastIndexOf("B");//结果:4

    //4.判断是否为空
    bool IsEmpty = vec.isEmpty();//结果为:false
    vec.clear();
    bool IsEmpty1 = vec.isEmpty();//结果为:true

3. 迭代器遍历

QVector 支持多种遍历方式


   QVector<int> vec = { 1,2,3,4,5 };
   qDebug();
   //方法1:Java风格迭代器,QT特有,不那么常用
   QVectorIterator<int> i(vec);
   while (i.hasNext())
   {
       qDebug() << i.next();
   }
   // 方法 2: STL 风格迭代器 (更现代,推荐)
   for (auto it = vec.begin(); it != vec.end(); ++it) {
       qDebug() << *it;
   }

   // 方法 3: 基于范围的 for 循环 (C++11,最简洁)
   for (const auto& value : vec) {
       qDebug() << value;
   }

   // 方法 4: 使用索引 (最直接)
   for (int i = 0; i < vec.size(); ++i) {
       qDebug() << vec[i];
   }

   // 方法 5: 使用 Qt 的 foreach 宏 (旧式,不推荐在新代码中使用)
   foreach(const int& value, vec) {
       qDebug() << value;
   }

4. 重要特性:隐式共享 (Implicit Sharing)

这是 Qt 容器一个非常强大的特性,也叫“写时复制”。

  • 核心思想: 当多个 QVector 对象赋值给彼此或作为参数传递时,它们并不会立即复制数据,而是共享同一份数据。只有当其中一个对象需要修改数据时(“写”操作),才会真正执行复制。

  • 好处: 极大地提高了传递值的效率,避免了不必要的深度拷贝,同时又保持了值语义的简洁性。


QVector<int> v1(1000000, 42); // 一个包含100万个元素的大向量
QVector<int> v2 = v1;         // 此时 v1 和 v2 共享同一份数据,开销极小

// 当修改 v2 时,才会发生真正的数据复制
v2[0] = 100; // 写操作触发“写时复制”,现在 v1 和 v2 拥有各自独立的数据

 

 
posted @ 2025-11-24 17:59  家煜宝宝  阅读(3)  评论(0)    收藏  举报