C++ 容器

C++ 容器(Containers)详解

在 C++ 标准库(STL, Standard Template Library)中,容器(Container) 是用于存储和管理一组对象的核心组件。它们封装了数据结构与常用操作,使开发者无需手动管理内存或实现底层算法,从而写出更安全、简洁、高效的代码。所有标准容器都是类模板(class templates)!


一、什么是容器?

容器是 C++ 标准库提供的、通用的类模板(class templates),用于组织和操作一组元素。

容器的核心特征:

  • 存储多个同类型元素 (如 intstring、自定义对象等);
  • 自动管理内存 (无需手动 new/delete);
  • 提供统一接口 :如 .size().empty().begin().end()
  • 支持迭代器遍历STL 算法 (如 std::sort, std::find);
  • 类型安全:编译期检查,避免越界(部分容器)。

注意:容器是 标准库预定义的类,不是用户"自定义类"------你使用它们,而不是从零实现它们。


二、容器的分类

C++ 标准将容器分为三大类:

1. 序列容器(Sequence Containers)

元素按线性顺序存储,位置由插入顺序决定。

容器 特点 典型用途
std::vector 动态数组,支持随机访问,尾部插入快 通用首选,替代 C 数组
std::deque 双端队列,首尾插入/删除快 需要双向高效操作
std::list 双向链表,任意位置插入/删除快 频繁中间插入/删除
std::forward_list 单向链表,内存开销最小 内存敏感场景
std::array 固定大小数组(编译期确定) 替代 C 风格数组,更安全
std::string 特化的字符序列容器 存储和操作文本

std::string 虽然用于文本,但技术上属于序列容器!


2. 关联容器(Associative Containers)

基于红黑树 实现,元素按键自动排序,查找效率为 O(log n)

容器 键是否唯一 是否有序 元素类型
std::set 唯一 Key
std::multiset 允许重复 Key
std::map 唯一 pair<const Key, Value>
std::multimap 允许重复 pair<const Key, Value>

🔒 map 的键(first)是 const,不可修改!


3. 无序关联容器(Unordered Associative Containers)

基于哈希表 实现,元素无序,平均查找效率为 O(1)

容器 键是否唯一 是否有序
std::unordered_set 唯一
std::unordered_multiset 允许重复
std::unordered_map 唯一
std::unordered_multimap 允许重复

⚡ 适合需要快速查找且不关心顺序的场景。


4. 容器适配器(Container Adapters)

基于其他容器封装,限制接口以提供特定行为。

适配器 默认底层容器 行为
std::stack deque 后进先出(LIFO)
std::queue deque 先进先出(FIFO)
std::priority_queue vector 按优先级出队(最大堆)

🛠️ 适配器不支持迭代器,不能遍历!


三、为什么使用容器? vs C 风格数组

对比项 C 风格数组 / 指针 C++ 容器
内存管理 手动(易泄漏、越界) 自动(RAII)
大小动态调整 ❌ 固定大小 vectorstring 等可自动扩容
安全性 低(无边界检查) 高(.at() 有检查,迭代器安全)
功能 仅存储 内置丰富操作(push_back, find, sort 等)
泛型支持 ✅ 模板 + STL 算法

🚫 示例:C 风格危险代码

c 复制代码
char buf[5];
strcpy(buf, "Hello!"); // 缓冲区溢出!

✅ C++ 安全替代

cpp 复制代码
std::string s = "Hello!"; // 自动分配 7 字节,安全!

四、容器的通用操作示例

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

int main() {
    // 1. 创建容器
    std::vector<int> vec = {3, 1, 4, 1, 5};

    // 2. 遍历(三种方式)
    for (size_t i = 0; i < vec.size(); ++i)        // 索引
        std::cout << vec[i] << " ";
    
    for (auto it = vec.begin(); it != vec.end(); ++it) // 迭代器
        std::cout << *it << " ";
    
    for (const auto& x : vec)                       // 范围 for
        std::cout << x << " ";

    // 3. 使用 STL 算法
    std::sort(vec.begin(), vec.end()); // 排序
    auto pos = std::find(vec.begin(), vec.end(), 4); // 查找

    // 4. string 作为容器
    std::string s = "hello";
    std::reverse(s.begin(), s.end()); // → "olleh"

    return 0;
}

五、常见误区澄清

误区 正确理解
"容器是自己写的类" ❌ 容器是 标准库提供的类模板
"所有类都是容器" ❌ 只有满足容器要求的类才是(如提供 begin()/end()
"string 不是容器" std::string标准序列容器
"容器一定防止越界" ⚠️ operator[] 不检查,.at() 才抛异常

六、总结

  • 容器是 C++ 现代编程的基石,应优先于 C 风格数组和指针;
  • std::vectorstd::string 是最常用的容器
  • 选择容器的原则
  • 需要随机访问?→ vector
  • 频繁中间插入?→ list
  • 快速按键查找?→ unordered_map
  • 只需栈/队列行为?→ stack / queue
  • 结合 auto、范围 for、STL 算法,写出简洁安全的代码!

记住:在 C++ 中,能用标准容器,就不要手写数组或链表!

相关推荐
郑州光合科技余经理9 小时前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo12310 小时前
matlab画图工具
开发语言·matlab
dustcell.10 小时前
haproxy七层代理
java·开发语言·前端
norlan_jame10 小时前
C-PHY与D-PHY差异
c语言·开发语言
哇哈哈202110 小时前
信号量和信号
linux·c++
多恩Stone10 小时前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
QQ40220549611 小时前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
遥遥江上月11 小时前
Node.js + Stagehand + Python 部署
开发语言·python·node.js
蜡笔小马11 小时前
21.Boost.Geometry disjoint、distance、envelope、equals、expand和for_each算法接口详解
c++·算法·boost
m0_5312371711 小时前
C语言-数组练习进阶
c语言·开发语言·算法