C++ STL 标准模板库介绍与入门

news2024/11/26 2:00:44

目录

1、概述

1.1、C++ 标准库

1.2、Boost库

2、STL 版本

2.1、HP 原始版本

2.2、P. J. 实现版本

2.3、RW 实现版本

2.4、SGI 实现版本

2.5、STLport 实现版本

3、STL 的六大组件

3.1、STL 六大组件构成

3.2、六大组件的交互关系

4、STL 的重要性

5、总结


VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具案例集锦(正在更新中...)https://blog.csdn.net/chenlycly/category_12279968.html?spm=1001.2014.3001.5482       STL标准模板库是C++标准库的重要组成部分,在C++代码中有着广泛的应用,今天就来详细讲述一下STL标准模板库的相关内容。

1、概述

       STL (standard template libaray - 标准模板库),是 C++ 标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。STL中几乎所有的代码都采用了模板类和模板函数的方式,所以有着很好的代码可重用性。

STL是一些容器、算法和其他一些组件的集合,所有容器和算法都是总结了几十年来算法和数据结构的研究成果,汇集了许多计算机专家学者经验的基础上实现的,因此可以说,STL 基本上达到了各种存储方法和相关算法的高度优化。

       我们在C++代码中常用的容器有vector、list、map和deque等,它们基于模板实现的方式,方便我们存放各种类型的数据。有了这些容器,我们一般不用自己再去实现一些数据结构,给我们带来了很大的便利,有效提高了我们编码的效率。除了容器之外,STL还提供了操作这些容器的算法函数,使用这些高效的算法函数,比直接遍历容器的效率要高很多,对于这一点可以查看我之前根据项目中的使用实例和体验撰写的文章:

VC++调用STL算法函数有效提升STL列表的搜索速度(附源码)https://blog.csdn.net/chenlycly/article/details/123943134

有的人可能会认为STL只包含容器相关的内容,其实大家平常使用的字符串类string、输入输出iostream、unique_ptr等智能指针,都是STL标准模板库中的。STL模板库不仅仅包含容器和迭代器。

       此外,说到STL,必须要说C++标准库;说到C++标准库,就要说到C++“准”标准库Boost库。所以这里简单地介绍一下C++标准库和Boost库。

1.1、C++ 标准库

        C++标准库(C++ Standard Library)提供了丰富的类库及库函数资源,这些内容总共在50个标准头文件中定义,包括语言支持、输入输出、通用工具、字符串操作、容器、迭代器、算法函数、数值操作等。

       C++标准库主要由C库、C++库和STL标准模板库构成,其中STL标准模板库在C++标准库中比重占了80%左右。在C++软件开发中,尽可能地利用C++标准库中的资源去完成。

1.2、Boost开源库

       Boost开源库由C++标准委员会的部分成员所设立的Boost社区开发并维护,使用了许多现代C++编程技术,其内容涵盖字符串处理、正则表达式、容器与数据结构、并发编程、函数式编程、泛型编程、设计模式实现等许多领域,极大地丰富了C++的功能和表现力,能够使C++软件开发更加简捷、灵活和高效。

Boost库由C++标准委员会库工作组成员发起,即许多 Boost 库的作者本身就是 C++ 标准委员会成员,因此,Boost“天然”成了标准库的后备,负责向新标准输送组件,这也使得 Boost 获得了“准”标准库的美誉!

       C++标准库从boost库中引入了大家熟知的正则表达式regex库智能指针unique_ptr(对应boost库中的scoped_ptr)、shared_ptr和weak_ptr函数适配bind库函数对象容器function等。

2、STL 版本

       自 1998 年 ANSI/ISO C++ 标准正式定案,C++ STL 规范版本正式通过以后,各个 C++ 编译器厂商在此标准的基础上,实现了满足自己需求的 C++ STL 泛型库,主要包括 HP STL、PJ STL、Rouge Wave STL、SGI STL等。

2.1、HP 原始版本

       HP STL 是 Alexandar Stepanov(STL 标准模板库之父)在惠普 Palo Alto 实验室工作时,与 Meng Lee 合作完成的。本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一要遵守的是,必修在文件中加上HP的版本声明和运用权限声明。 

HP STL 是 C++ STL 的第一个实现版本,其它版本的 C++ STL 一般是以 HP STL 为蓝本实现出来的。不过,现在已经很少直接使用此版本的 STL 了。

2.2、P. J. 实现版本

       由 P. J. Plauger 开发,继承自 HP 版本,该版本不开源,不能公开、修改或贩卖。该版本不开源也是合法的,因为HP没要求强迫要求其衍生产品必须开源。

       该版本被微软 Visual C++ 采用,缺陷是,可读性比较低,符号命名也比较怪异。但我们在Visual Studio中阅读该版本的实现源码时,感觉还好,也没传说中那么难读。

其实 PJ STL 是 P.J.Plauger 公司的产品,尽管该公司当时只有 3 个人。

2.3、RW 实现版本

       由 Rouge Wage 公司开发,继承自 HP 版本,被Borland公司的 C+ + Builder 采用。该版本也不是开源的,不能公开、修改或贩卖,这个版本的可读性还不错。

       值得一提的是,尽管 Rouge Wave STL 的性能不是很好,但 C++ Builder 对 C++ 语言标准的支持还算不错,所以在一定程度上使 Rouge Wave STL 的表现得以改善。但遗憾的是,由于 Rouge Wave STL 长期没有更新且不完全符合标准,因此 Rouge Wave STL 在 6.0 版本时改用了 STLport 版本(之后的版本也都采用了 STLport),不过考虑到和之前版本的兼容,6.0 版本中依旧保留了 Rouge Wave STL。

Rouge Wave 公司在 C++ 程序库领域应该说是鼎鼎大名,对 C++ 标准化的过程出力甚多。不过 Rouge Wave STL 版本不仅更新频率慢,费用还高,基于这两个原因,Borland 在 6.0 版本决定弃用 Rouge Wave STL 而改用 STLport。

2.4、SGI 实现版本

       由 Silicon Graphics Computer Systems,Inc 公司开发,继承自 HP 版本。该版本被 Linux GCC 采用,可移植性好, 在 Linux 平台上的性能非常出色。该版本是开源的,可公开、修改甚至贩卖。

这个版本STL也是Alexander Stepanov主导开发的(HP版本就是他开发的),Alexander Stepanov 在离开 HP 之后,就加入到了 SGI 公司,并和 Matt Austern 等人开发了 SGI STL。

       无论是符号命名,还是编程风格,这个版本的可读性非常高。如果大家要学习 STL源码,推荐大家看这个版本的源码实现。侯捷老师的经典书籍《STL源码剖析》,也是基于这个版本展开的。

2.5、STLport 实现版本

      为了使 SGI STL 的基本代码都适用于 VC++ 和 C++ Builder 等多种编译器,俄国人 Boris Fomitchev 建立了一个 free 项目来开发 STLport,此版本 STL 是开放源码的。

由于 Rouge Wave STL 长期没有更新且不完全符合标准,因此 Rouge Wave STL 在 6.0 版本时改用了 STLport 版本,之后的版本也都采用了 STLport。

3、STL 的六大组件

       STL标准模板库是C++标准库的重要组成部分,因此所有的C++编译器都支持STL,都选用各自的STL版本。STL 提供了六大组件,彼此组合套用协同工作。

3.1、STL 六大组件构成

       这六大组件分别是:

  • 容器(Containers):各种数据结构,如 vector、list、deque、set、map 等。从实现的角度来看,容器是一种 class template。
  • 算法(Algorithms):各种常用算法,提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作,比如 sort、search、copy、erase。从实现的角度来看,STL 算法是一种 function template。
  • 迭代器(Iterators):迭代器用于遍历对象集合的元素,扮演容器与算法之间的胶合剂,是所谓的“泛型指针”,共有 5 种类型,以及其他衍生变化。从实现角度来看,迭代器是一种将 operator*、operator->、operator++、operator-- 等指针操作予以重载的 class template。所有的 STL 容器附带有自己专属的迭代器,因为只有容器设计者才知道如何遍历自己的元素。
  • 仿函数(Functors):也称为函数对象(Function object),行为类似函数,可作为算法的某种策略。从实现角度来看,仿函数是一种重载了 operator() 的 class 或者 class template。
  • 适配器(Adaptors):一种用来修饰容器或者仿函数或迭代器接口的东西。例如 STL 提供的 queue 和 stack,就是一种空间配接器,因为它们的底部完全借助于 deque。
  • 分配器(Allocators):也称为空间配置器,负责空间的配置与管理。从实现的角度来看,配置器是一个实现了动态配置空间、空间管理、空间释放的 class template。

3.2、六大组件的交互关系

        六大组件的交互关系如下:

3.2.1、容器

       一个容器就是一些特定类型对象的集合。STL 中容器分为两大类,序列式容器和关联式容器。

       序列式容器(sequential container)为程序员提供了控制元素存储和访问顺序的能力。这种顺序不依赖于元素的值,而是与元素加入容器时的位置相对应。

       除了序列式容器外,标准库还定义了三个序列式容器适配器:stack、queue 和 priority_queue。适配器是标准库中的一个通用概念,容器、迭代器和函数都有适配器。本质上,一个适配器是一种机制,能使某种事物的行为看起来像另外一种事物一样。

       和序列式容器对应的是关联式容器(associative-container),关联容器中的元素是按关键字来保存和访问的。关联容器支持高效的关键字查找和访问,STL 有两个主要的关联容器:map 和 set。 

3.2.2、容器迭代器

       迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。迭代器就如同一个指针。事实上,C++ 的指针也是一种迭代器。但是,迭代器不仅仅是指针,因此你不能认为他们一定具有地址值。例如,一个数组索引,也可以认为是一种迭代器。

       迭代器有各种不同的创建方法。程序可能把迭代器作为一个变量创建。一个 STL 容器类可能为了使用一个特定类型的数据而创建一个迭代器。作为指针,必须能够使用 * 操作符类获取数据。还可以使用其他数学操作符如 ++ 操作符用来递增迭代器,以访问容器中的下一个对象。

如果迭代器到达了容器中的最后一个元素的后面,则迭代器变成 past-the-end 值。使用一个 past-the-end 值得指针来访问对象是非法的,就好像使用 NULL 或为初始化的指针一样。

3.2.3、算法

       STL 通过函数模板提供了很多作用于容器的通用算法,例如查找、插入、删除、排序等,这些算法均需要引入头文件 <algorithm>。

       所有的 STL 算法都作用在由迭代器 [first, last) 所标示出来的区间上,可以分为两大类:

  • 质变算法(mutating algorithms):运算过程中会更改区间内迭代器所指的元素内容,如分割(partition)、删除(remove)等算法。
  • 非质变算法(nonmutating algorithms):运算过程中不会更改区间内迭代器所指的元素内容,如匹配(search),计数(count)等算法。

       所有泛型算法的前两个参数都是一对迭代器,通常称为 first 和 last,用以标示算法的操作区间。注意,将无效的迭代器传给某个算法,虽然是一种错误,但不保证能够在编译期间被捕捉出来。

4、STL 的重要性

       要论STL的重要性要从几个维度去看。

       从学习的角度看,通过学习STL源码实现,可以学习到很多数据结构的经典实现,对于提升个人能力有好的促进作用。

       从面试的角度看,STL也面试时常问的主题,比如比较容器的优缺点(比如vector和list)、使用容器时的注意事项、某些容器的内部实现机制或思想等。

       从工作的角度看,STL实现了很多常用的数据结构以及操作这些数据结构的算法函数,我们基本不需要自己再去重复造轮子,我们可以站在前人的肩膀上,高效快速进行开发。在大家日常的C++代码中,大规模地使用了vector、list、map等容器及相关的高效算法函数,给日常开发工作带来了很大的便利,有效地提升了大家的开发效率。

5、总结

       大家在工作中多使用STL容器,积累STL容器的使用经验,在使用过程中搞清楚STL相关知识点和使用时的注意事项。大家如果想学习STL内部源码与设计思想,推荐看侯捷老师的经典著作《STL源码剖析》。

       虽然STL很强大,给我们带来很多便利,但STL也是有缺陷的。STL为了追求更高的效率,内部实现很复杂,比如类型萃取,迭代器萃取等。STL不支持线程安全,在并发操作时需要我们自己加锁保护。此外,STL是用模板实现的,保证了代码的通用及可重用性,但也带来了代码膨胀问题。使用到STL的地方,都会拷贝一份实例化实现代码,在一定程度上会有代码膨胀问题,会增加二进制文件的大小。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java spring MVC之RESTful快速开发

我这里有个一springboot项目 我在启动类同目录下创建了一个目录 目录名叫 controller 里面有一个UserController diam结构是这样的 package com.example.threshold.controller;import com.example.threshold.user; import org.springframework.stereotype.Controller; import…

平衡二叉树理论详解

文章目录 基本概念平衡二叉树插入结点LL&#xff08;左单旋&#xff09;RR&#xff08;右单旋&#xff09;LR&#xff08;左右旋&#xff09;RL&#xff08;右左旋&#xff09; 示例插入推导过程 基本概念 平衡二叉树是一棵空树或它的左右两个子树的高度差的绝对值不超过1&…

Maven ( 二 ) 项目应用

4.资源管理 4.0.pom.xml Maven的pom.xml是一个项目对象模型(Project Object Model)&#xff0c;它是Maven项目的构建文件。它描述了一个项目的基本信息&#xff0c;包括项目依赖、插件、仓库等信息。 下面是一个简单的pom.xml示例&#xff1a; <project xmlns"http…

深度学习用于医学预后-第二课第三周4-7节-关于事件的时间数据,认识处理删失数据

在本课中&#xff0c;我们将讨论生存数据。为了能够对生存进行建模&#xff0c;我们需要能够以我们可以处理的形式表示数据。 主要的挑战是删失数据&#xff0c;这是一种特殊形式的缺失数据。我们接下来将要研究这一点。 在这节课中&#xff0c;我们将谈论生存数据和删失。 …

LeetCode 96 不同的二叉搜索树

题目&#xff1a; 给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;5 示例 2&#xff1a; 输入&#xff1a;n 1 …

第七章:C语言的操作符

说起操作符大家都不陌生&#xff0c;从我们最初的 - c * / 加减乘除&#xff0c;到更加深奥的操作符&#xff0c;而今天我要有完整的系统来理清楚C语言的操作符到底有什么&#xff0c;和它们相关的用法&#xff0c;话不多说&#xff0c;直接走进今天的主题----C语言的操…

保护个人隐私和数据安全的方法与策略

引言 随着信息技术的普及和发展&#xff0c;我们享受到了便捷的互联网服务&#xff0c;但与此同时&#xff0c;个人隐私和数据安全问题也日益受到威胁。在这个所谓的"裸奔"时代&#xff0c;网络攻击、数据泄露和隐私侵犯已经成为常态。然而&#xff0c;我们并不无助…

sysfs文件系统

sysfs系统介绍 sysfs系统sysfs系统是什么&#xff1f;koject的内核对象模型基础kobject结构体定义kest bus如何管理driver和devicebus_type 结构体 小知识什么是挂载mount命令 &#x1f4cc;————本章重点————&#x1f4cc; &#x1f517;了解sysfs系统概念; &#x1f5…

布谷鸟hash算法的并行化实现(一)

由于本人最近在写一个项目&#xff0c;为了实现数据查找以及数据修改部分的快速操作&#xff0c;所以采用hash对数据进行存储&#xff0c;而在此过程中接触到了布谷鸟hash&#xff0c;觉得这个hash算法还是很有意思并且高效&#xff0c;所以想着进行一些记录&#xff0c;本系列…

一文带你快速掌握如何读懂 YonBuilder移动开发 的项目源码

本文将通过四大步的简单讲述&#xff0c;让新手开发者朋友们快速掌握阅读YonBuilder移动开发项目源码的技巧方法。 1.读懂代码的第一步&#xff0c;了解项目的整体文件结构 CSS: 存放css样式的文件&#xff1b; feature&#xff1a;猜测是用来存放特征文件的&#xff0c;实际…

了解投影坐标系统,并在精美的地图上探索

投影坐标系简介 地球椭球体表面也是个曲面&#xff0c;而我们日常生活中的地图及量测空间通常是二维平面&#xff0c;因此在地图制图和线性量测时首先要考虑把曲面转化成平面。由于球面上任何一点的位置是用地理坐标&#xff08;λ&#xff0c;φ&#xff09;表示的&#xff0…

计算机三级网络技术总结(更新中)

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f35f;欢迎来到前端初见的博文&#xff0c;本文主要讲解我计算机三级网络技术&#x1f35f; &#x1f468;‍&#x1f527; 个人主页 : 前端初见 &#x1f95e;喜欢的朋友可以关注一下&#…

BEV专栏(二)从BEVFormer看BEV流程(下篇)

前言 书接上回&#xff0c;在上一篇文章中&#xff0c;我们介绍了BEVFormer这一先进的BEV算法。在本篇文章中&#xff0c;我们将深入探讨BEVFormer的实现细节&#xff0c;旨在帮助读者更深入地理解BEVFormer的工作原理和性能表现。 本教程禁止转载。同时&#xff0c;本教程来自…

【maven】自定义构建maven的jar包依赖

前言 自己定义自己的maven的jar包依赖&#xff0c;本地版本。 实现 pom.xml pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSche…

车载软件架构——闲聊几句AUTOSAR BSW(五)

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 我们并不必要为了和谐,而时刻保持通情达理;我们需要具备的是,偶尔有肚量欣然承认在某些方面我们可能会有些不可理喻。该有主见的时候能掷地有声地镇得住场…

车载基础软件——基础软件验证平台(网络管理和诊断)

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 我们并不必要为了和谐&#xff0c;而时刻保持通情达理&#xff1b;我们需要具备的是&#xff0c;偶尔有肚量欣然承…

部署packstack及问题总结

目录 一、部署packstack 1.1 简介 1.2 性能搭配 1.3 准备工作 1.4 安装 二、出现的问题 2.1 安装中断临时文件 2.2 提示某个安装包出错 2.3 leatherman版本太高 三、安装成功 一、部署packstack 1.1 简介 对于openstack初学者而言&#xff0c;传统部署openstack流程…

MQ-rabbitMQ_基础篇

MQ-rabbitMQ_基础篇 1.MQ1.1什么是MQ1,2应用 2.常见消息中间件协议&#xff08;模型&#xff09;2.1JMS模型&#xff08;协议&#xff09;2.2AMQP协议 3.RabbitMQ3.1六种工作模式3.1.1Hello Word简单模式3.1.2word queues 工作队列能者多劳 3.1.3Publish/Subscribe 发布与订阅模…

在SwissTargetsPrediction数据库中预测成分靶点

1.对筛选的多肽成分进行靶点预测&#xff1a; ①用Uniport中的蛋白进行一系列操作&#xff08;水解&#xff0c;挑选2~8短肽&#xff0c;活性预测&#xff0c;毒性&#xff0c;过敏性预测&#xff0c;胃肠吸收度&#xff0c;半衰期和苦味的预测、生物活性功能预测&#xff09;…

mybatis连接池源码分析

文章目录 前言一、PooledDataSourceFactory二、获取连接三、归还连接 前言 其实大部分连接池的代码都大同小异&#xff0c;总体获取连接&#xff0c;归还连接逻辑大都相同。希望通过阅读本文章&#xff0c;能给你带来帮助。 测试用例 public void testMybatis()throws Excepti…