简介: CSDN博客专家、《Android系统多媒体进阶实战》作者

博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址: Audio工程师进阶系列原创干货持续更新中……】🚀
Android多媒体专栏地址: 多媒体系统工程师系列原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课 🚀
专题四:Android15快速自定义与集成音效实战课 🚀
专题五:Android15音频策略实战课 🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例) 🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🌻1. 前言

本篇目的:C++ 进阶之有序容器 vector:用法实例

🌻2. C++ 有序容器 vector 介绍

  1. 基本概念
    std::vector 是 C++ 标准模板库(STL)中最常用的序列式容器。它在内存中表现为一块连续的动态数组,能够根据元素的增加自动进行扩容,并允许通过下标进行高效的随机访问。
  2. 功能
    支持动态调整大小、高效的尾部插入与删除、以及快速的随机访问。它封装了底层内存管理的复杂性,提供了迭代器支持,可以无缝对接大多数 STL 算法(如 std::sort)。
  3. 使用限制
    由于其连续内存的特性,在容器头部或中间插入/删除元素需要移动大量数据,时间复杂度为 O ( n ) O(n) O(n)。此外,扩容时可能会发生内存重新分配,导致原有的迭代器、指针或引用失效。
  4. 性能特性
    提供 O ( 1 ) O(1) O(1) 时间复杂度的随机访问。尾部插入在未触发扩容时为 O ( 1 ) O(1) O(1),触发扩容时为均摊 O ( 1 ) O(1) O(1)。由于数据物理存储连续,对 CPU 缓存极为友好。
  5. 使用场景
    适用于需要频繁随机访问、数据量动态变化但主要在末尾操作的场景。在音视频开发中,常用于存储原始采样数据、管理对象列表或作为临时缓冲区。

🌻3. 代码实例

🌻3.1 基础操作与多种遍历方式
  1. 应用场景
    演示 vector 的初始化、元素添加以及如何使用现代 C++ 的不同方式进行高效遍历。
  2. 用法实例
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // 初始化并添加元素
    std::vector<int> vec = {10, 20, 30};
    vec.push_back(40);

    // 方式1:Range-based for loop (推荐)
    for (const auto& val : vec) {
        std::cout << val << " ";
    }
    std::cout << std::endl;

    // 方式2:使用迭代器与 lambda 表达式
    std::for_each(vec.begin(), vec.end(), [](int v) {
        std::cout << v << " ";
    });
    std::cout << std::endl;

    return 0;
}

🌻3.2 性能优化:使用 reserve 避免频繁重分配
  1. 应用场景
    在预知数据规模的情况下,通过预留空间减少动态扩容带来的内存申请与拷贝开销。
  2. 用法实例
#include <iostream>
#include <vector>
#include <chrono>

int main() {
    std::vector<int> vec;
    
    // 获取当前容量和大小
    std::cout << "Initial capacity: " << vec.capacity() << std::endl;

    // 预留 1000 个元素的空间
    vec.reserve(1000);
    std::cout << "Capacity after reserve: " << vec.capacity() << std::endl;

    // 此时插入 1000 个元素不会触发任何内存重新分配
    for (int i = 0; i < 1000; ++i) {
        vec.push_back(i);
    }

    std::cout << "Final size: " << vec.size() << std::endl;
    return 0;
}

🌻3.3 进阶用法:emplace_back 与移动语义
  1. 应用场景
    对比 push_backemplace_back,演示如何在容器内部直接构造对象,从而消除不必要的拷贝或移动。
  2. 用法实例
#include <iostream>
#include <vector>
#include <string>

struct AudioTrack {
    std::string name;
    AudioTrack(std::string n) : name(std::move(n)) {
        std::cout << "Constructed: " << name << std::endl;
    }
};

int main() {
    std::vector<AudioTrack> playlist;

    // push_back 会先构造一个临时对象,再将其移动或拷贝进 vector
    std::cout << "--- push_back ---" << std::endl;
    playlist.push_back(AudioTrack("track_01.mp3"));

    // emplace_back 直接在 vector 管理的内存中构造对象
    std::cout << "--- emplace_back ---" << std::endl;
    playlist.emplace_back("track_02.wav"); 

    return 0;
}


🌻3.4 std::vector 总结

关键字 功能描述 典型应用
push_back / emplace_back 向尾部添加元素 动态数据采集、队列构建
reserve() 预分配内存空间 大规模数据插入前的性能优化
at() / operator[] 随机访问元素 快速查找、数组式索引操作
data() 获取底层连续数组指针 与 C 风格 API(如 ALSA/FFmpeg)交互

更多推荐