C++ 学习杂记04:std::vector 类

概述

std::vector是 C++ 标准模板库(STL)中提供的动态数组容器。它能够在运行时动态调整大小,提供随机访问迭代器,是 C++ 中最常用的容器之一。

头文件

复制代码
#include <vector>

类模板声明

复制代码
template<
    class T,
    class Allocator = std::allocator<T>
> class vector;

构造函数

1. 默认构造函数

复制代码
std::vector<T> vec;  // 创建空vector

2. 指定大小构造函数

复制代码
std::vector<T> vec(10);           // 10个默认初始化的元素
std::vector<T> vec(10, value);    // 10个值为value的元素

3. 范围构造函数

复制代码
std::vector<T> vec(other.begin(), other.end());  // 从迭代器范围构造

4. 拷贝构造函数

复制代码
std::vector<T> vec(other);  // 深拷贝

5. 初始化列表构造函数

复制代码
std::vector<T> vec = {1, 2, 3, 4, 5};

常用成员函数

元素访问

复制代码
// 返回指定位置的引用,不进行边界检查
T& operator[](size_type pos);
const T& operator[](size_type pos) const;

// 返回指定位置的引用,进行边界检查(可能抛出std::out_of_range)
T& at(size_type pos);
const T& at(size_type pos) const;

// 返回第一个元素的引用
T& front();
const T& front() const;

// 返回最后一个元素的引用
T& back();
const T& back() const;

// 返回底层数组的指针
T* data() noexcept;
const T* data() const noexcept;

容量相关

复制代码
// 检查是否为空
bool empty() const noexcept;

// 返回元素数量
size_type size() const noexcept;

// 返回最大可能元素数量
size_type max_size() const noexcept;

// 预留容量,减少重新分配次数
void reserve(size_type new_cap);

// 返回当前分配的存储容量
size_type capacity() const noexcept;

// 请求移除未使用的容量
void shrink_to_fit();

修改操作

复制代码
// 清空所有元素
void clear() noexcept;

// 在末尾插入元素
void push_back(const T& value);
void push_back(T&& value);

// 移除末尾元素
void pop_back();

// 在指定位置插入元素
iterator insert(const_iterator pos, const T& value);
iterator insert(const_iterator pos, T&& value);
iterator insert(const_iterator pos, size_type count, const T& value);

// 擦除指定位置的元素
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);

// 调整容器大小
void resize(size_type count);
void resize(size_type count, const T& value);

// 交换两个vector的内容
void swap(vector& other) noexcept;

示例代码

基本使用

复制代码
#include <iostream>
#include <vector>

int main() {
    // 创建vector
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    
    // 添加元素
    numbers.push_back(6);
    
    // 访问元素
    std::cout << "第一个元素: " << numbers.front() << std::endl;
    std::cout << "最后一个元素: " << numbers.back() << std::endl;
    std::cout << "第三个元素: " << numbers[2] << std::endl;
    
    // 遍历vector
    std::cout << "所有元素: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    // 使用迭代器
    std::cout << "使用迭代器: ";
    for (auto it = numbers.begin(); it != numbers.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

容量管理示例

复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec;
    
    std::cout << "初始容量: " << vec.capacity() << std::endl;
    
    // 预留空间以提高性能
    vec.reserve(100);
    std::cout << "预留100个元素后的容量: " << vec.capacity() << std::endl;
    
    // 添加元素
    for (int i = 0; i < 50; ++i) {
        vec.push_back(i);
    }
    
    std::cout << "添加50个元素后的大小: " << vec.size() << std::endl;
    std::cout << "添加50个元素后的容量: " << vec.capacity() << std::endl;
    
    return 0;
}

插入和删除示例

复制代码
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 5, 6};
    
    // 在位置3插入元素4
    auto it = vec.begin() + 3;
    vec.insert(it, 4);
    
    // 删除元素2
    vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());
    
    // 输出结果
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

性能特征

时间复杂度

  • 随机访问:O(1)

  • 在末尾插入/删除:O(1)(平均情况,不考虑重新分配)

  • 在开头或中间插入/删除:O(n)

  • 查找:O(n)(无序情况下)

空间复杂度

  • 连续内存存储

  • 可能需要额外的内存用于管理

使用建议

优点

  1. 随机访问:支持常数时间复杂度的随机访问

  2. 缓存友好:数据连续存储,缓存局部性好

  3. 动态扩容:自动管理内存,无需手动分配

  4. 丰富接口:提供丰富的成员函数和算法支持

注意事项

  1. 中间插入/删除:在vector中间插入或删除元素效率较低

  2. 内存重新分配:扩容时可能导致迭代器失效

  3. 预留空间 :如果知道大致元素数量,使用reserve()提高性能

  4. 大对象:存储大对象时,考虑使用指针或智能指针

迭代器失效规则

  • 插入元素时:如果导致重新分配,所有迭代器、指针、引用失效

  • 插入元素时:如果未重新分配,插入点后的迭代器失效

  • 删除元素时:被删除元素后的迭代器失效

  • reserve():如果增加容量,所有迭代器、指针、引用可能失效

相关算法

复制代码
#include <algorithm>

// 排序
std::sort(vec.begin(), vec.end());

// 查找
auto it = std::find(vec.begin(), vec.end(), value);

// 反转
std::reverse(vec.begin(), vec.end());

// 删除特定元素
vec.erase(std::remove(vec.begin(), vec.end(), value), vec.end());

总结

std::vector是 C++ 中最常用、最通用的容器之一。它结合了数组的随机访问效率和动态数组的灵活性,适用于大多数需要顺序存储数据的场景。正确使用 vector可以提高代码的性能和可维护性。

相关推荐
郝学胜_神的一滴8 小时前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
卷无止境2 天前
C++ 的Eigen 库全解析
c++
卷无止境2 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端
郝学胜_神的一滴2 天前
CMake 27:缓存变量的特性、语法、类型与实操全解
c++·cmake
博客18004 天前
酷宝的使用方法,超好用的免费界面库,C++、MFC可用
c++·mfc·界面库·库来帮·酷宝
郝学胜_神的一滴4 天前
CMake 026:属性体系精讲、四大作用域全解 & 实战代码落地
c++·cmake
众少成多积小致巨5 天前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
clint4569 天前
C++进阶(1)——前景提要
c++
夜悊9 天前
C++代码示例:进制数简单生成工具
c++
郝学胜_神的一滴9 天前
CMake 021: IF 条件判据详诠
c++·cmake