关于C++STL的总结(基础使用和底层原理)

STL是什么?

STL即(Standard Template Library)标准模板库,提供了常见的数据结构和算法函数等,其下共包含六大组件:

  1. 容器
  2. 算法
  3. 迭代器
  4. 仿函数
  5. 适配器
  6. 空间配置器

本篇重点介绍容器的使用和简单的底层实现原理,其它的部分简略带过
六大组件互相的关系大致如下图:
在这里插入图片描述


容器

容器即是存储数据的类模板,本质即是封装了常用的数据结构,主要可以分为两类:

  • 序列式容器
    关联式容器将相同类型的元素以有序的方式线性组织起来,如下:
    1. vector:动态数组,支持快速的随机访问
    2. deque:双端队列,支持快速插入和删除
    3. list:双向循环链表,支持快速插入和删除,但不支持随机访问
  • 关联式容器
    1. set/multiset:集合/多重集合(key形式)
    2. map/multimap:映射/多重映射(key-value形式)
    3. unordered_set/unordered_multiset:无序集合/无序多重集合
      unordered_map/unordered_multimap:无序映射/无序多重映射(哈希表)

还有些常见的“容器”,如stack/queue和priority_queue,这些则是属于容器适配器的组件,它们是在基本容器(vector,deque等)之上提供特定接口的适配器


迭代器

什么是迭代器?迭代器本质就是用于遍历和操作容器中的元素的一种工具,它提供了访问容器元素的方法,可以简单理解为数组名(即指针)
为什么需要迭代器?迭代器最重要的意义是提供了一种统一的方式来操作容器中的元素,无需在意元素类型,底层数据结构实现细节,都通过迭代器来进行访问
迭代器的类型大致分为以下五种:

  1. 单向迭代器:仅支持++操作(forward_list)
  2. 双向迭代器:仅支持++和–操作(list)
  3. 随机访问迭代器:支持+和-的操作(deque、vector)
  4. 反向迭代器:即与正向迭代器相反的操作的迭代器
  5. 常量迭代器:不支持修改的迭代器

不同的迭代器只是性质不一样,但使用起来时都是相同的使用iterator进行操作,iterator底层的实现可能是指针,也可能是封装的其它数据结构,如list的迭代器封装的即是链表节点,无论封装的什么,都是为了统一访问元素的方式


算法、仿函数

算法和仿函数即是为了方便C++开发,提前写好的一些常用算法和“函数”,便于使用
算法常见的即sort,swap,max/min等,详情可以去看官方文档,重点说一下仿函数

  • 什么是仿函数?
    仿函数又被称为函数对象,本质是一个类,重载了函数调用运算符operator(),使得这个类的对象可以像函数一样被调用,故此又称仿函数

  • 常见的即自定义Compare比较类,实例如下(实际中可以提供更多样不同的类型的比较)

    class Compare {
    public:
        bool operator()(int num1, int num2) {
            return num1 < num2;
        }
    };
    
    int main() {
        Compare cmp;
        std::cout << cmp(1, 2) << std::endl;  
       	sort(v.begin(), v.end(), Compare());
    	sort(v.begin(), v.end(), greater<int>());
    	for(auto i : v){
    		cout << i << endl;
    	}
    	sort(v.begin(), v.end(), less<int>());
    	for(auto i : v){
    		cout << i << endl;
    	}
        return 0;
    }
    
    
    

实例中的less和greater即是functional中为我们提供的仿函数类,一般都是用于sort等函数的函数比较器使用


适配器和空间配置器

适配器

在C++的STL中,适配器是一种设计模式,它的目的是使得原本接口不兼容的类可以一起工作。在STL中,适配器主要有三种类型:

  1. 容器适配器:容器适配器是一个封装了序列容器的类模板,它在一般序列容器的基础上提供了一些不同的功能²。例如,stack是一个封装了deque容器的适配器类模板,默认实现的是一个后入先出(Last-In-First-Out,LIFO)的压入栈⁴。queuestack大同小异,只是开放的函数是符合先进先出(FIFO)原则的函数。

  2. 函数对象适配器:函数对象适配器可以将一般迭代器的赋值(assign)操作,转化为插入(insert)操作²。有专司头端插入的front_insert_iterator,专司尾部插入的back_insert_iterator,还有就是insert_iterator,其可以实现从任意位置执行插入操作。

  3. 迭代器适配器:迭代器适配器可以将迭代器绑定到一个stream(数据流)对象身上。绑定到istream对象(例如std::cin)者,称为istream_iterator,拥有输入能力;绑定到ostream对象(例如std::cout)者,称为ostream_iterator,拥有输出能力。


空间配置器

C++的STL中的空间配置器是一个非常重要的组件,它负责内存的配置和管理。空间配置器的存在可能平常并不太能感知到,但其为STL的操作对象提供了存储空间(内存池)。

什么是空间配置器?
空间配置器是一个实现了动态空间配置、空间管理、空间释放的class template。它的主要任务是为STL容器分配和释放内存。

为什么需要空间配置器?
空间配置器的存在可以帮助我们更有效地管理内存。它可以解决小块内存频繁申请释放带来的性能问题,以及小块内存带来的内存碎片问题。

空间配置器是如何工作的?
STL的空间配置器有两级:第一级配置器和第二级配置器。

  1. 第一级配置器:当配置区块大于128bytes时,将其视作足够大,直接使用malloc和free。

  2. 第二级配置器:当配置区块小于128bytes时,将其视作过小,为降低额外负担,采用内存池的管理方式。内存池的思想是一次向heap申请一块很大的内存,如果申请小块内存的话就直接到内存池中去要。

在STL中,空间配置器的基本操作包括:

  • 内存配置:由成员函数allocate()负责。
  • 内存释放:由成员函数deallocate()负责。
  • 对象构造:由成员函数construct()负责。
  • 对象析构:由成员函数destroy()负责。

关于容器的详解后续会补充STL各个常用的容器的模拟实现,以此了解其底层原理(待)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

推荐六款图片编辑软件

图片编辑、抠图、拼图、压缩、放大、加字体、转格式等各种功能应有尽有&#xff0c;收藏这一篇就够了&#xff01; 综合编辑&#xff1a;图片编辑助手 这是一款电脑软件&#xff0c;里面有超多图片处理功能&#xff0c;压缩图片到指定大小、消除任意位置的图片水印、按指定大小…

【C++】---STL之vector的模拟实现

【C】---STL之vector的模拟实现 一、vector在源码中的结构&#xff1a;二、vector类的实现&#xff1a;1、vector的构造2、析构3、拷贝构造4、赋值运算符重载5、迭代器6、operator[ ]7、size()8、capacity()9、reserve()10、resize()11、empty()12、push_back()13、pop_back()1…

如何在PostgreSQL中设置自动清理过期数据的策略

文章目录 方法一&#xff1a;使用临时表和定期清理步骤&#xff1a;示例代码&#xff1a;创建临时表&#xff1a;定期清理脚本&#xff08;bash psql&#xff09;&#xff1a; 方法二&#xff1a;使用分区表和定期清理步骤&#xff1a;示例代码&#xff1a;创建分区表&#xf…

《内向者优势》:不要低估一个内向的人

#世界读书日 作者主页&#xff1a; &#x1f517;进朱者赤的博客 精选专栏&#xff1a;&#x1f517;经典算法 作者简介&#xff1a;阿里非典型程序员一枚 &#xff0c;记录在大厂的打怪升级之路。 一起学习Java、大数据、数据结构算法&#xff08;公众号同名&#xff09; ❤…

Redis篇:缓存更新策略最佳实践

前景&#xff1a; 缓存更新是redis为了节约内存而设计出来的一个东西&#xff0c;主要是因为内存数据宝贵&#xff0c;当我们向redis插入太多数据&#xff0c;此时就可能会导致缓存中的数据过多&#xff0c;所以redis会对部分数据进行更新&#xff0c;或者把他叫为淘汰更合适&a…

Vue3的监听属性watch和计算属性computed

监听属性watch 计算属性computed 一、监听属性watch watch 的第一个参数可以是不同形式的“数据源&#xff0c;watch 可以监听以下几种数据&#xff1a; 一个 ref (包括计算属性)、 一个响应式对象、 一个 getter 函数、 或多个数据源组成的数组 watch 的参数:监视的回调&…

代码随想录算法训练营第三十五天|860.柠檬水找零、406.根据身高重建队列、452. 用最少数量的箭引爆气球

860. 柠檬水找零 思路&#xff1a; 只需要维护三种金额的数量&#xff0c;5&#xff0c;10和20。 有如下三种情况&#xff1a; 情况一&#xff1a;账单是5&#xff0c;直接收下。情况二&#xff1a;账单是10&#xff0c;消耗一个5&#xff0c;增加一个10情况三&#xff1a;…

好友关注-实现分页查询收邮箱

9.5好友关注-实现分页查询收邮箱 需求&#xff1a;在个人主页的“关注”卡片中&#xff0c;查询并展示推送的Blog信息&#xff1a; 具体操作如下&#xff1a; 1、每次查询完成后&#xff0c;我们要分析出查询出数据的最小时间戳&#xff0c;这个值会作为下一次查询的条件 2…

考研党打印资料怎么使用云打印服务?

对于准备考研的同学们来说&#xff0c;在备考的时候需要准备许多资料&#xff0c;这些资料的打印费用成为了考研党的巨额支出。那么在生活费有限的情况下&#xff0c;考研党打印资料最好是选择云打印服务&#xff0c;因为易绘创云打印服务低至5分钱/页还包邮。那么考研党打印资…

Pytest精通指南(28)钩子函数-测试报告(pytest-html)

文章目录 前言应用场景插件安装参数分析使用方法拓展-定制化报告 前言 在软件开发过程中&#xff0c;测试是确保代码质量的关键环节。 而测试报告则是测试过程中不可或缺的输出物&#xff0c;它为我们提供了关于测试用例执行情况的详细信息&#xff0c;帮助我们快速定位和解决问…

服务器(AIX、Linux、UNIX)性能监视器工具【nmon】使用介绍

目录 ■nmon简介 1.安装 2.使用简介 3.使用&#xff08;具体使用的例子【CPU】【内存】&#xff09; 4.采集数据 5.查看log&#xff08;根据结果&#xff0c;生成报表&#xff09; 6.分析结果 ■nmon简介 nmon&#xff08;"Nigels performance Monitor"&…

比特币成长的代价

作者&#xff1a;Jeffrey Tucker&#xff0c;作家和总裁。曾就经济、技术、社会哲学和文化等话题广泛发表演讲。编译&#xff1a;秦晋 2017 年之后参与比特币市场的人遇到了与之前的人不同的操作和理想。如今&#xff0c;没有人会太在意之前的事情&#xff0c;说的是 2010-2016…

SL3038 耐压150V恒压芯片 60V降24V 72V降12V降压IC

SL3038 是一款恒压芯片&#xff0c;其耐压值为 150V。这意味着它可以在高达 150V 的电压下工作而不会损坏。现在&#xff0c;让我们来讨论您提到的两个降压应用&#xff1a;从 60V 降到 24V 和从 72V 降到 12V。 1. 60V 降到 24V&#xff1a; 输入电压&#xff1a;60V 输出电…

02 IO口的操作

文章目录 前言一、IO的概念1.IO接口2.IO端口 二、CPU和外设进行数据传输的方法1.程序控制方式1.1 无条件1.2 查询方式 2.中断方式3.DMA方式 一、方法介绍和代码编写1.前置知识2.程序方式1.1 无条件方式1.1.1 打开对应的GPIO口1.1.2 初始化对应的GPIO引脚1.1.2.1 推挽输出1.1.2.…

【Hadoop】-Hive部署[12]

目录 思考 VMware虚拟机部署 规划 步骤1&#xff1a;安装MySQL数据库 步骤2&#xff1a;配置Hadoop 步骤3&#xff1a;下载解压Hive 步骤4&#xff1a;提供MySQL Driver包 步骤5&#xff1a;配置Hive 步骤6&#xff1a;初始化元数据库 步骤7&#xff1a;启动Hive&…

TDSQL同一个所属Set显示3个备份节点

欢迎关注“数据库运维之道”公众号&#xff0c;一起学习数据库技术! 本期将为大家分享《TDSQL同一个所属Set显示3个备份节点》的处置案例。 关键词&#xff1a;分布式数据库、TDSQL、备份节点 1、问题描述 登录赤兔管理平台&#xff0c;单击左侧导航栏“实例管理/集群管理”…

漫谈-AI 时代的信息模型

模型化- 数字化转型的重要基石 在各行各业推行数字化转型过程中&#xff0c;构建信息化模型十分重要&#xff0c;它是数字化转型的基石。事实上&#xff0c;数字化转型的核心是“万物皆模型”&#xff0c;在工业领域&#xff0c;以德国为主导的工业4.0 发展进程中&#xff0c;…

Access denied for user ‘zabbix‘@‘localhost‘ (using password: NO)

现象 排查过程 进入数据库show grants for zabbixlocalhost;select host,user from mysql.user;cat /etc/zabbix/zabbix_server.conf | grep DB | grep -vE ‘#|$’cat /etc/zabbix/web/zabbix.conf.php | grep DB 解决办法 mysql 8.0以下 DPassword123.com mariadb -e "…

java多线程-并发和并行

进程 并发 进程中的线程是由CPU进行调度的&#xff0c;但是CPU能够处理的进程数量有限为了保证所有的线程都在运行&#xff0c;CPU会快速切换&#xff0c;给外界的感觉就是所有的线程都在运行&#xff0c;这就是并发。 并行

【力扣 Hot100 | 第六天】4.21(最长连续序列)

文章目录 10.最长连续序列10.1题目10.2解法&#xff1a;哈希法10.2.1哈希思路10.2.2代码实现 10.最长连续序列 10.1题目 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时…
最新文章