C++,STL 六大组件:容器、迭代器、算法、函数对象、适配器、分配器

请添加图片描述

文章目录

  • 引言
  • 一、容器(Containers)
    • 主要分类
  • 二、迭代器(Iterators)
  • 三、算法(Algorithms)
  • 四、函数对象(Functors)
  • 五、适配器(Adapters)
  • 六、分配器(Allocators)
  • 结语


引言

C++ 标准模板库(Standard Template Library, STL)是泛型编程的典范,其核心思想是通过高度抽象的组件实现数据结构和算法的解耦。STL 的成功离不开其六大核心组件的协同工作:容器(Containers)、迭代器(Iterators)、算法(Algorithms)、函数对象(Functors)、适配器(Adapters)和分配器(Allocators)。这些组件各司其职,共同构建了一个高效、灵活且通用的编程框架。本文将深入解析这六大组件的功能、用法及其相互关系。


一、容器(Containers)

容器是 STL 的基础,用于存储和管理数据集合。所有容器均通过模板实现,支持任意数据类型,且提供统一的操作接口。

主要分类

  1. 顺序容器:

    • vector:动态数组,支持快速随机访问,尾部插入高效。
    • list:双向链表,插入/删除高效,但随机访问性能差。
    • deque:双端队列,支持头部和尾部高效插入。
  2. 关联容器:

    • set/multiset:基于红黑树的有序集合,元素自动排序。
    • map/multimap:键值对集合,键唯一(map)或允许多键(multimap)。
  3. 无序容器:(C++11+)

    • unordered_set/unordered_map:基于哈希表,查询效率接近 O(1)。

示例代码:

#include <vector>
#include <unordered_map>std::vector<int> nums = {1, 2, 3};  // 动态数组
std::unordered_map<std::string, int> wordCount = {{"apple", 5}, {"banana", 3}};  // 哈希表

二、迭代器(Iterators)

迭代器是访问容器元素的通用接口,类似于指针,但抽象了底层容器的实现细节。它充当容器和算法之间的桥梁,使得算法可以独立于容器类型工作。

迭代器分类:

  1. 输入迭代器:只读,单向移动(如 istream_iterator)。
  2. 输出迭代器:只写,单向移动(如 ostream_iterator)。
  3. 前向迭代器:可读写,单向移动(如 forward_list 的迭代器)。
  4. 双向迭代器:可双向移动(如 list 的迭代器)。
  5. 随机访问迭代器:支持随机跳转(如 vector 的迭代器)。

示例代码:

std::vector<int> vec = {3, 1, 4, 1, 5};
for (auto it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";  // 通过迭代器遍历容器
}

三、算法(Algorithms)

STL 提供了超过 100 种泛型算法,涵盖排序、查找、数值计算等操作。这些算法通过迭代器操作容器,无需依赖具体容器类型。

常用算法:

  • 排序与查找:sort(), find(), binary_search()
  • 修改操作:copy(), replace(), reverse()
  • 数值计算:accumulate(), inner_product()

示例代码:

#include <algorithm>
std::vector<int> nums = {5, 3, 9, 1};
std::sort(nums.begin(), nums.end());  // 排序算法
auto it = std::find(nums.begin(), nums.end(), 9);  // 查找元素

四、函数对象(Functors)

函数对象(仿函数)是重载了 operator() 的类实例,可以像函数一样调用。它常用于定制算法的行为(如比较、转换逻辑)。

常见用途:

  • 比较器:std::less<>, std::greater<>
  • 算术操作:std::plus<>, std::multiplies<>
  • 自定义逻辑:结合 Lambda 表达式(C++11+)

示例代码:

#include <functional>
std::vector<int> nums = {1, 4, 2, 8};
// 使用 greater<> 降序排序
std::sort(nums.begin(), nums.end(), std::greater<int>());// 使用 Lambda 表达式过滤偶数
auto isEven = [](int x) { return x % 2 == 0; };
auto it = std::find_if(nums.begin(), nums.end(), isEven);

五、适配器(Adapters)

适配器基于现有组件扩展功能,通过限制或调整接口满足特定需求。

常见适配器类型:

  1. 容器适配器
    • stack:基于 deque 或 list 实现后进先出(LIFO)。
    • queue:基于 deque 实现先进先出(FIFO)。
    • priority_queue:基于 vector 实现堆结构。
  2. 迭代器适配器
    • reverse_iterator:反向遍历容器。
    • back_insert_iterator:尾部插入元素的迭代器。

示例代码:

#include <stack>
std::stack<int> s;  // 默认基于 deque
s.push(10);
s.push(20);
s.pop();  // 弹出 20

六、分配器(Allocators)

分配器负责管理容器的内存分配与释放。默认使用 std::allocator,通常无需直接操作,但在需要优化内存性能(如内存池)时非常有用。

核心功能:

  • allocate():分配内存块。
  • deallocate():释放内存块。
  • construct()/destroy():构造或析构对象。

示例场景:

// 自定义分配器(伪代码)
template<typename T>
class CustomAllocator {// 实现 allocate, deallocate 等方法
};std::vector<int, CustomAllocator<int>> customVec;  // 使用自定义分配器

结语

STL 的六大组件通过高度解耦的设计,实现了数据管理、算法逻辑和内存控制的分离。这种设计不仅提高了代码的复用性和性能,还让开发者能够专注于业务逻辑而非底层细节。

  • 容器负责存储数据,迭代器提供访问接口,算法实现通用逻辑。
  • 函数对象和适配器扩展了灵活性,分配器优化了内存管理。

掌握这六大组件,是高效使用 STL 的关键。建议通过实际项目练习其组合应用(如结合 Lambda 与算法、使用容器适配器实现特定数据结构),并参考《Effective STL》等书籍深入理解最佳实践。

STL 不仅是工具库,更是一种编程哲学的体现——通过抽象和泛型,让代码更简洁、更强大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/10207.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

996引擎 - NPC-添加NPC引擎自带形象

996引擎 - NPC-添加NPC引擎自带形象 截图参考添加NPC参考资料截图参考 添加NPC 编辑NPC表:Envir\DATA\cfg_npclist.xls 1.1. 需要临时隐藏NPC时可以在id前加 // 1.2. 如果NPC朝向不对,可以调整dir 列。(按8方向,上是0顺时针数。我这里给的4) 1.3. 形象代码:NPC代码、怪物…

【懒删除堆】力扣2349. 设计数字容器系统

设计一个数字容器系统&#xff0c;可以实现以下功能&#xff1a; 在系统中给定下标处 插入 或者 替换 一个数字。 返回 系统中给定数字的最小下标。 请你实现一个 NumberContainers 类&#xff1a; NumberContainers() 初始化数字容器系统。 void change(int index, int numb…

利用飞书机器人进行 - ArXiv自动化检索推荐

相关作者的Github仓库 ArXivToday-Lark 使用教程 Step1 新建机器人 根据飞书官方机器人使用手册&#xff0c;新建自定义机器人&#xff0c;并记录好webhook地址&#xff0c;后续将在配置文件中更新该地址。 可以先完成到后续步骤之前&#xff0c;后续的步骤与安全相关&…

SpringBoot 日志

目录 一. 日志概述 二. 日志的使用 1. 打印日志 (1) 获取日志对象 (2) 输出要打印的内容 2. 日志框架简介 (1) 门面模式简介 (2) SLF4J 框架简介 3. 日志的格式 4. 日志的级别 5. 日志配置 (1) 配置日志级别 (2) 日志持久化存储 ① 配置日志文件名 ② 配置日志的…

RK3568中使用QT opencv(显示基础图像)

文章目录 一、查看对应的开发环境是否有opencv的库二、QT使用opencv 一、查看对应的开发环境是否有opencv的库 在开发板中的/usr/lib目录下查看是否有opencv的库&#xff1a; 这里使用的是正点原子的ubuntu虚拟机&#xff0c;在他的虚拟机里面已经安装好了opencv的库。 二、…

LMI Gocator GO_SDK VS2019引用配置

LMI SDK在VS2019中的引用是真的坑爹,总结一下经验,希望后来的人能少走弯路.大致内容如下: &#xff08;1&#xff09; 环境变量 &#xff08;2&#xff09;C/C 附加包含目录 E:\GWQ\Gocator\GO_SDK\Gocator\GoSdk E:\GWQ\Gocator\GO_SDK\Platform\kApi &#xff08;3&#…

模型I/O

文章目录 什么是模型I/O模型I/O功能之输出解析器输出解析器的功能输出解析器的使用Pydantic JSON输出解析器结构化输出解析器 什么是模型I/O 模型I/O在所有LLM应用中&#xff0c;核心元素无疑都是模型本身。与模型进行有效的交互是实现高效、灵活和可扩展应用的关键。LangChain…

C语言练习(31)

有5个学生&#xff0c;每个学生有3门课程的成绩&#xff0c;从键盘输入以上数据&#xff08;包括学号、姓名、3门课程成绩&#xff09;&#xff0c;计算出平均成绩&#xff0c;将原有数据和计算出的平均分数存放在磁盘文件stud中。 设5名学生的学号、姓名和3门课程成绩如下&am…

【Block总结】DynamicFilter,动态滤波器降低计算复杂度,替换传统的MHSA|即插即用

论文信息 标题: FFT-based Dynamic Token Mixer for Vision 论文链接: https://arxiv.org/pdf/2303.03932 关键词: 深度学习、计算机视觉、对象检测、分割 GitHub链接: https://github.com/okojoalg/dfformer 创新点 本论文提出了一种新的标记混合器&#xff08;token mix…

「AI学习笔记」深度学习的起源与发展:从神经网络到大数据(二)

深度学习&#xff08;DL&#xff09;是现代人工智能&#xff08;AI&#xff09;的核心之一&#xff0c;但它并不是一夜之间出现的技术。从最初的理论提出到如今的广泛应用&#xff0c;深度学习经历了几乎一个世纪的不断探索与发展。今天&#xff0c;我们一起回顾深度学习的历史…

Axure PR 9 旋转效果 设计交互

大家好&#xff0c;我是大明同学。 这期内容&#xff0c;我们将学习Axure中的旋转效果设计与交互技巧。 旋转 创建旋转效果所需的元件 1.打开一个新的 RP 文件并在画布上打开 Page 1。 2.在元件库中拖出一个按钮元件。 创建交互 创建按钮交互状态 1.选中按钮元件&#xf…

【外文原版书阅读】《机器学习前置知识》2.用看电影推荐的例子带你深入了解向量点积在机器学习的作用

目录 3.3 Where Are You Looking, Vector? The Dot Product 个人主页&#xff1a;Icomi 大家好&#xff0c;我是Icomi&#xff0c;本专栏是我阅读外文原版书《Before Machine Learning》对于文章中我认为能够增进线性代数与机器学习之间的理解的内容的一个输出&#xff0c;希望…

论文阅读(八):结构方程模型用于研究数量遗传学中的因果表型网络

1.论文链接&#xff1a;Structural Equation Models for Studying Causal Phenotype Networks in Quantitative Genetics 摘要&#xff1a; 表型性状可能在它们之间发挥因果作用。例如&#xff0c;农业物种的高产可能会增加某些疾病的易感性&#xff0c;相反&#xff0c;疾病的…

每日一题——序列化二叉树

序列化二叉树 BM39 序列化二叉树题目描述序列化反序列化 示例示例1示例2 解题思路序列化过程反序列化过程 代码实现代码说明复杂度分析总结 BM39 序列化二叉树 题目描述 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树。二叉树的序列化是将二叉树按照某种遍历方式…

JVM_程序计数器的作用、特点、线程私有、本地方法的概述

①. 程序计数器 ①. 作用 (是用来存储指向下一条指令的地址,也即将要执行的指令代码。由执行引擎读取下一条指令) ②. 特点(是线程私有的 、不会存在内存溢出) ③. 注意:在物理上实现程序计数器是在寄存器实现的,整个cpu中最快的一个执行单元 ④. 它是唯一一个在java虚拟机规…

Attention--人工智能领域的核心技术

1. Attention 的全称与基本概念 在人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;领域&#xff0c;Attention 机制的全称是 Attention Mechanism&#xff08;注意力机制&#xff09;。它是一种能够动态分配计算资源&#xff0c;使模型在处理输入数据…

机器学习2 (笔记)(朴素贝叶斯,集成学习,KNN和matlab运用)

朴素贝叶斯模型 贝叶斯定理&#xff1a; 常见类型 算法流程 优缺点 集成学习算法 基本原理 常见方法 KNN&#xff08;聚类模型&#xff09; 算法性质&#xff1a; 核心原理&#xff1a; 算法流程 优缺点 matlab中的运用 朴素贝叶斯模型 朴素贝叶斯模型是基于贝叶斯…

智慧园区系统助力企业智能化升级实现管理效率与安全性全方位提升

内容概要 在当今数字化转型的浪潮中&#xff0c;企业面临着前所未有的挑战和机遇。智慧园区系统作为一种创新性解决方案&#xff0c;正在快速崛起&#xff0c;帮助企业实现全面的智能化升级。这套系统不仅仅是一个简单的软件工具&#xff0c;而是一个强大的综合管理平台&#…

【视频+图文详解】HTML基础4-html标签的基本使用

图文教程 html标签的基本使用 无序列表 作用&#xff1a;定义一个没有顺序的列表结构 由两个标签组成&#xff1a;<ul>以及<li>&#xff08;两个标签都属于容器级标签&#xff0c;其中ul只能嵌套li标签&#xff0c;但li标签能嵌套任何标签&#xff0c;甚至ul标…

电子电气架构 --- 在智能座舱基础上定义人机交互

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…