ITPub博客

首页 > 应用开发 > IT综合 > C++ Vector容器详解:动态数组原理与应用实践

C++ Vector容器详解:动态数组原理与应用实践

投稿 IT综合 作者:bhluo 时间:2026-01-29 11:34:47 0 删除 编辑

《C++ Vector容器详解:动态数组原理与应用实践》


在C++标准模板库中,`std::vector`是最常用且功能强大的序列容器,它提供了动态数组的功能,能够根据需要在运行时自动调整大小。作为连续存储的容器,vector在性能、便利性和安全性之间实现了良好平衡。


**动态数组核心架构**


vector本质上是一个封装良好的动态数组,它在堆上分配连续内存空间来存储元素:


```cpp

#include <vector>

#include <iostream>


void vectorBasicDemo() {

    // 多种初始化方式

    std::vector<int> vec1;                     // 空vector

    std::vector<int> vec2(5, 10);              // 5个元素,每个都是10

    std::vector<int> vec3 = {1, 2, 3, 4, 5};   // 初始化列表

    std::vector<int> vec4(vec3.begin(), vec3.end()); // 迭代器范围

    

    // 添加和访问元素

    vec1.push_back(100);

    vec1.push_back(200);

    vec1.push_back(300);

    

    // 随机访问元素

    std::cout << "第一个元素: " << vec1[0] << std::endl;

    std::cout << "第二个元素: " << vec1.at(1) << std::endl; // 带边界检查

    std::cout << "最后一个元素: " << vec1.back() << std::endl;

    

    // 迭代器访问

    std::cout << "所有元素: ";

    for (auto it = vec1.begin(); it != vec1.end(); ++it) {

        std::cout << *it << " ";

    }

    std::cout << std::endl;

}

```


**容量管理与动态增长**


vector的核心特性之一是能够动态调整容量,这通过三个关键概念实现:size、capacity和reserve:


```cpp

void vectorCapacityDemo() {

    std::vector<int> numbers;

    

    std::cout << "初始状态 - 大小: " << numbers.size()

              << ", 容量: " << numbers.capacity() << std::endl;

    

    // 添加元素,观察容量变化

    for (int i = 0; i < 20; ++i) {

        numbers.push_back(i);

        std::cout << "添加元素 " << i 

                  << " - 大小: " << numbers.size()

                  << ", 容量: " << numbers.capacity() << std::endl;

    }

    

    // 预分配容量以优化性能

    std::vector<int> optimized;

    optimized.reserve(1000);  // 预分配1000个元素的空间

    

    std::cout << "\n优化后vector - 大小: " << optimized.size()

              << ", 容量: " << optimized.capacity() << std::endl;

    

    // 缩减容量到实际大小

    numbers.shrink_to_fit();

    std::cout << "缩减后容量: " << numbers.capacity() << std::endl;

}

```


**高效内存管理与操作**


vector的连续内存特性使得某些操作特别高效:


```cpp

void vectorOperationsDemo() {

    std::vector<int> data = {1, 2, 3, 4, 5};

    

    // 中间插入(可能引起元素移动)

    auto pos = data.begin() + 2;

    data.insert(pos, 100);

    

    std::cout << "插入后: ";

    for (int n : data) std::cout << n << " ";

    std::cout << std::endl;

    

    // 删除元素

    data.erase(data.begin() + 1);  // 删除第二个元素

    data.pop_back();               // 删除最后一个元素

    

    std::cout << "删除后: ";

    for (int n : data) std::cout << n << " ";

    std::cout << std::endl;

    

    // 清空vector

    data.clear();

    std::cout << "清空后大小: " << data.size() << std::endl;

    

    // 批量操作

    std::vector<int> source = {10, 20, 30, 40, 50};

    std::vector<int> destination;

    

    // 移动元素(C++11及以上)

    destination = std::move(source);

    

    std::cout << "\n移动后:\n";

    std::cout << "目标vector大小: " << destination.size() << std::endl;

    std::cout << "源vector大小: " << source.size() << std::endl;

}

```


**迭代器失效问题**


理解vector操作对迭代器的影响至关重要:


```cpp

void iteratorInvalidationDemo() {

    std::vector<int> nums = {1, 2, 3, 4, 5};

    

    // 获取迭代器

    auto it = nums.begin() + 2;  // 指向第三个元素

    

    std::cout << "原始迭代器指向: " << *it << std::endl;

    

    // 情况1:插入操作可能使所有迭代器失效

    nums.push_back(6);

    // it = nums.begin() + 2;  // 需要重新获取迭代器

    

    // 情况2:删除操作会使被删除元素及其后的迭代器失效

    it = nums.begin() + 2;  // 重新获取

    nums.erase(nums.begin() + 1);

    

    std::cout << "删除后迭代器指向: ";

    if (it != nums.end()) {

        std::cout << *it << std::endl;

    } else {

        std::cout << "迭代器已失效" << std::endl;

    }

    

    // 安全做法:使用索引或重新获取迭代器

    size_t index = 2;

    nums.erase(nums.begin() + index);

    // 后续通过索引计算新的迭代器位置

}

```


**性能优化策略**


正确使用vector需要理解其性能特征:


```cpp

#include <chrono>


void performanceOptimization() {

    const size_t elementCount = 1000000;

    

    // 方法1:不预分配容量

    {

        std::vector<int> vec;

        auto start = std::chrono::high_resolution_clock::now();

        

        for (size_t i = 0; i < elementCount; ++i) {

            vec.push_back(i);

        }

        

        auto end = std::chrono::high_resolution_clock::now();

        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

        std::cout << "无预分配耗时: " << duration.count() << "ms" << std::endl;

    }

    

    // 方法2:预分配容量

    {

        std::vector<int> vec;

        vec.reserve(elementCount);

        auto start = std::chrono::high_resolution_clock::now();

        

        for (size_t i = 0; i < elementCount; ++i) {

            vec.push_back(i);

        }

        

        auto end = std::chrono::high_resolution_clock::now();

        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

        std::cout << "预分配耗时: " << duration.count() << "ms" << std::endl;

<"z4.j9k5.org.cn"><"j6.j9k5.org.cn"><"n3.j9k5.org.cn"><"w7.j9k5.org.cn">

    }

}

```


**二维vector与高级应用**


vector可以嵌套使用,创建多维数据结构:


```cpp

void multiDimensionalVector() {

    // 二维vector的声明和初始化

    std::vector<std::vector<int>> matrix;

    

    // 初始化3x3矩阵

    for (int i = 0; i < 3; ++i) {

        std::vector<int> row(3, 0);  // 创建3个0的行

        matrix.push_back(row);

    }

    

    // 访问和修改元素

    matrix[1][1] = 5;  // 设置中心元素

    

    // 使用初始化列表的简洁方式

    std::vector<std::vector<int>> grid = {

        {1, 2, 3},

        {4, 5, 6},

        {7, 8, 9}

    };

    

    // 遍历二维vector

    std::cout << "二维矩阵内容:\n";

    for (const auto& row : grid) {

        for (int val : row) {

            std::cout << val << " ";

        }

        std::cout << std::endl;

    }

    

    // 不规则二维结构

    std::vector<std::vector<int>> triangle;

    for (int i = 0; i < 5; ++i) {

        triangle.push_back(std::vector<int>(i + 1, i + 1));

    }

}

```


**与标准算法结合使用**


vector与STL算法库完美配合:


```cpp

#include <algorithm>

#include <numeric>


void vectorWithAlgorithms() {

    std::vector<int> numbers = {5, 2, 8, 1, 9, 3};

    

    // 排序

    std::sort(numbers.begin(), numbers.end());

    std::cout << "排序后: ";

    for (int n : numbers) std::cout << n << " ";

    std::cout << std::endl;

    

    // 查找

    auto result = std::find(numbers.begin(), numbers.end(), 8);

    if (result != numbers.end()) {

        std::cout << "找到元素8,位置索引: " 

                  << std::distance(numbers.begin(), result) << std::endl;

    }

    

    // 累加

    int sum = std::accumulate(numbers.begin(), numbers.end(), 0);

    std::cout << "元素总和: " << sum << std::endl;

    

    // 转换

    std::vector<int> doubled;

    std::transform(numbers.begin(), numbers.end(), 

                   std::back_inserter(doubled),

                   [](int x) { return x * 2; });

    

    std::cout << "加倍后: ";

    for (int n : doubled) std::cout << n << " ";

    std::cout << std::endl;

}

```


**自定义类型存储与移动语义**


vector支持存储自定义类型,并受益于C++11的移动语义:


```cpp

class Person {

private:

    std::string name;

    int age;

    

public:

    Person(std::string n, int a) : name(std::move(n)), age(a) {

        std::cout << "构造Person: " << name << std::endl;

<"g9.j9k5.org.cn"><"q2.j9k5.org.cn"><"t5.j9k5.org.cn">

    }

    

    // 移动构造函数

    Person(Person&& other) noexcept 

        : name(std::move(other.name)), age(other.age) {

        std::cout << "移动构造Person: " << name << std::endl;

    }

    

    // 拷贝构造函数

    Person(const Person& other) : name(other.name), age(other.age) {

        std::cout << "拷贝构造Person: " << name << std::endl;

    }

    

    void display() const {

        std::cout << name << " (" << age << "岁)" << std::endl;

    }

};


void customTypeVector() {

    std::vector<Person> people;

    

    // 使用emplace_back直接在vector中构造对象

    people.emplace_back("张三", 25);

    people.emplace_back("李四", 30);

    

    std::cout << "\n人员列表:\n";

    for (const auto& person : people) {

        person.display();

    }

    

    // 预分配容量减少重新分配

    std::vector<Person> optimizedList;

    optimizedList.reserve(10);  // 预分配空间

    

    for (int i = 0; i < 5; ++i) {

        optimizedList.emplace_back("用户" + std::to_string(i), 20 + i);

    }

}

```


**使用建议与最佳实践**


1. **预分配容量**:已知元素数量时使用`reserve()`提高性能

2. **使用emplace**:C++11及以上使用`emplace_back`避免不必要的拷贝

3. **选择合适数据结构**:频繁中间插入考虑使用list或deque

4. **避免迭代器失效**:在插入删除操作后重新获取迭代器

5. **使用范围for循环**:简化遍历代码


```cpp

void bestPractices() {

    // 最佳实践示例

    std::vector<int> data;

    data.reserve(1000);  // 预分配

    

    // 使用emplace_back避免临时对象

    std::vector<std::string> strings;

    strings.emplace_back("高效构造");

    

    // 使用范围for循环

    for (const auto& str : strings) {

        std::cout << str << " ";

    }

    

    // 使用算法替代手动循环

    std::sort(data.begin(), data.end());

}

```


**总结**


std::vector作为C++标准库中最常用的容器,以其连续存储、动态扩展、高效随机访问的特性成为大多数场景的首选。理解vector的内部机制——特别是容量管理、迭代器失效规则和性能特征——对于编写高效稳定的C++代码至关重要。


在实际开发中,vector的合理使用需要考虑具体需求:对于需要频繁随机访问、内存连续性重要的场景,vector通常是最佳选择;对于频繁在中间位置插入删除的场景,可能需要考虑其他容器。通过掌握vector的特性和最佳实践,开发者能够充分利用这一强大工具,构建高效可靠的C++应用程序。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/19545/viewspace-3109353/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2015-11-01

  • 博文量
    895
  • 访问量
    934872