C++之STL理论基础

1.基本概念

STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称。虽然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间。
STL的从广义上讲分为三部分:algorithm(算法)、container(容器)和iterator(迭代器),容器和算法通过迭代器可以进行无缝地连接。几乎所有的代码都采 用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。在C++标准中,STL被组织为下面的13个头文件:
<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack> 和<utility>
此外,C++的STL还包括仿函数、适配器以及空间适配器。

2.STL的优势

  1. STL是C++的一部分,因此不用额外安装什么,它被内建在你的编译器之内。
  2. STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但是这种分离确实使得STL变得非常通用。例如,在STL的vector容器中,可以放入元素(对象)、基础数据类型变量、指针;STL的sort()函数可以用来操作vector,list等容器。
  3. 程序员可以不用思考STL具体的实现过程,只要能够熟练使用STL就OK了。这样他们就可以把精力放在程序开发的别的方面。
  4. STL具有高可重用性,高性能,高移植性,跨平台的优点。
  5. STL有以下这些好处,我们知道STL无疑是最值得C++程序员骄傲的一部分。每一个C++程序员都应该好好学习STL。只有能够熟练使用STL的程序员,才是好的C++程序员。

高可重用性: STL中几乎所有的代码都采用了模板类和模版函数的方式实现,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。
高性能:如map可以高效地从十万条记录里面查找出指定的记录,因为map是采用红黑树的变体实现的。(红黑树是平横二叉树的一种)
高移植性:如在项目A上用STL编写的模块,可以直接移植到项目B上。
跨平台:如用windows的Visual Studio编写的代码可以在Mac OS的XCode上直接编译。

3.容器

  在实际的开发过程中,数据结构本身的重要性不会逊于操作于数据结构的算法的重要性,当程序中存在着对时间要求很高的部分时,数据结构的选择就显得更加重要。
  经典的数据结构数量有限,但是我们常常重复着一些为了实现向量、链表等结构而编写的代码,这些代码都十分相似,只是为了适应不同数据的变化而在细节上有所出入。STL容器就为我们提供了这样的方便,它允许我们重复利用已有的代码实现构造自己的特定类型下的数据结构,通过设置一些模板,STL容器对最常用的数据结构提供了支持,这些模板的参数允许我们指定容器中元素的数据类型,可以将我们许多重复而乏味的工作简化。
  在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对象的指针,这种对象类型就叫做容器。

容器部分主要由头文件<vector>,<list>,<deque>,<set>,<map>,<stack> 和<queue> 组成

容器的分类:

标准C++的STL框架中的容器主要有两大类:

序列式容器(Sequence containers): 将一组具有相同类型T的对象,以严格的线性形式组织在一起。
每个元素都有固定位置--取决于插入时机和地点,和元素值无关。如:

vector(向量)、deque(double-ended queue双端队列)、list(表)

序列容器可以视为数组和链表的推广。

关联式容器(Associated containers): 关联容器的特点是(键)有序的,即元素是按预定义的键顺序(如升序)插入的。
元素位置取决于特定的排序准则,和插入顺序无关 :

set<Key>(集合)multiset<Key>(多重集合)map<Key, T>(映射/映像)multimap<Key, T>(多重映射)hash_set<Key, H>(散列集)hash_map<Key, T, H>(散列映射)hash_multimap<Key, T, H>(散列多映射)

容器适配器(container adapter)不是独立的容器,只是某种容器的变种,它提供原容器的一个专用的受限接口。特别是,容器适配器不提供迭代器。

stack<T>(栈)queue<T>(队列)priority_queue<T>(优先队列)

这里写图片描述

4.迭代器

  软件设计有一个基本原则,所有的问题都可以通过引进一个间接层来简化,这种简化在STL中就是用迭代器来完成的。概括来说,迭代器在STL中用来将算法和容器联系起来,起着一种黏和剂的作用。几乎STL提供的所有算法都是通过迭代器存取元素序列进行工作的,每一个容器都定义了其本身所专有的迭代器,用以存取容器中的元素。
  迭代器部分主要由头文件<utility>,<iterator>和<memory>组成。<utility>是一个很小的头文件,它包括了贯穿使用在STL中的几个模板的声明,<iterator>中提供了迭代器使用的许多方法,而对于<memory>的描述则十分的困难,它以不同寻常的方式为容器中的元素分配存储空间,同时也为某些算法执行期间产生 的临时对象提供机制,<memory>中的主要部分是模板类allocator,它负责产生所有容器中的默认分配器。
  简单来说,迭代器就是一个指针,指向具体容器中的具体元素,解引用以后的数据类型就是容器元素的数据类型。是容器和算法的粘合剂,是一个间接层。

5.算法

  函数库对数据类型的选择对其可重用性起着至关重要的作用。举例来说,一个求方根的函数,在使用浮点数作为其参数类型的情况下的可重用性肯定比使用整型作为它的参数类性要高。而C++通过模板的机制允许推迟对某些类型的选择,直到真正想使用模板或者说对模板进行特化的时候,STL就利用了这一点提 供了相当多的有用算法。它是在一个有效的框架中完成这些算法的——可以将所有的类型划分为少数的几类,然后就可以在模版的参数中使用一种类型替换掉同一种类中的其他类型。
  STL提供了大约100个实现算法的模版函数,比如算法for_each将为指定序列中的每一个元素调用指定的函数,stable_sort以 你所指定的规则对序列进行稳定性排序等等。这样一来,只要熟悉了STL之后,许多代码可以被大大的化简,只需要通过调用一两个算法模板,就可以完成所需要 的功能并大大地提升效率。
  算法部分主要由头文件,和组 成。是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。中则定义了一些模板类,用以声明函数对象。

说白了就是一系列的函数集合,这些函数通常是模板函数。

代码示例

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;void func1()
{// 定义一个容器:用来存数据、存 int 数据vector<int> a;a.push_back(1);a.push_back(2);a.push_back(1);a.push_back(3);a.push_back(1);a.push_back(4);a.push_back(1);a.push_back(5);// 迭代器,提供了遍历容器的统一方法//vector<int>::iterator it;//for (it = a.begin(); it != a.end(); it++)//{//  cout << *it << " ";//}//cout << endl;vector<int>::iterator it = a.begin();while (it != a.end()){cout << *it << " ";it++;}cout << endl;// 算法:用来处理容器中的数据,通过迭代器int num = count(a.begin(), a.end(), 1);cout << num << endl;
}class Student 
{
public:Student (int id, int age){this->id = id;this->age = age;}void print(){printf ("id = %d, age = %d\n", id, age);}
private:int id;int age;
};void func2()
{Student s1(10,20);Student s2(11,21);Student s3(12,22);Student s4(13,23);Student s5(14,24);vector<Student> v;v.push_back(s1);v.push_back(s2);v.push_back(s3);v.push_back(s4);v.push_back(s5);vector<Student>::iterator it = v.begin();while (it != v.end()){it->print();it++;}
}void func3()
{Student s1(10,20);Student s2(11,21);Student s3(12,22);Student s4(13,23);Student s5(14,24);vector<Student*> v;
//  v.push_back(&s1);
//  v.push_back(&s2);
//  v.push_back(&s3);
//  v.push_back(&s4);
//  v.push_back(&s5);v.push_back(new Student(10,20));v.push_back(new Student(11,21));v.push_back(new Student(12,22));v.push_back(new Student(13,23));v.push_back(new Student(14,24));vector<Student*>::iterator it = v.begin();while (it != v.end()){(*it)->print();it++;}
}int main()
{// func1();// func2();func3();return 0;
}

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

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

相关文章

解决maven打包报错:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、报错经历&#xff1a; 今天使用eclipse通过maven install打war包的时候&#xff0c;出现了下图所示的错误 二、问题分析&#xff1a…

STL之Vector

1.简介 vector是将元素置于一个动态数组中加以管理的容器。可以随机存取元素&#xff08;支持索引值直接存取&#xff0c;用[]操作符或at()方法&#xff0c;还支持迭代器方式存取&#xff09;。   vector尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比…

解决 : Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 执行 maven install 命令报错如题&#xff1a; Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:comp…

Docker 镜像 重命名

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 镜像改名命令格式&#xff1a; # 命令格式&#xff1a;docker tag 镜像id 仓库&#xff1a;标签或&#xff1a;docker tag 旧镜…

Java蓝桥杯02——第二题集锦:生日蜡烛、星期一、方格计数、猴子分香蕉

第二题 生日蜡烛(结果填空) 某君从某年开始每年都举办一次生日party&#xff0c;并且每次都要吹熄与年龄相同根数的蜡烛。 现在算起来&#xff0c;他一共吹熄了236根蜡烛。 请问&#xff0c;他从多少岁开始过生日party的&#xff1f; 请填写他开始过生日party的年龄数。 注意&a…

解决:Error response from daemon: Get https://index.docker.io/v1/search?q=openjdkn=25: dial tcp: looku

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 我只是想查一个 mysql 镜像。执行命令&#xff1a; docker search mysql 。报错如下&#xff1a; Error response from daemon…

安装 Git ( Windows、linux、Mac)

安装 Git 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 是时候动手尝试下 Git 了&#xff0c;不过得先安装好它。有许多种安装方式&#xff0c;主要分为两种&#xff0c;一种是通过编…

STL之函数适配器

1.理论知识 2.常用函数适配器 标准库提供一组函数适配器&#xff0c;用来特殊化或者扩展一元和二元函数对象。常用适配器是&#xff1a; 1绑定器&#xff08;binder&#xff09;: binder通过把二元函数对象的一个实参绑定到一个特殊的值上&#xff0c;将其转换成一元函数对象…

pyqt5 + pyinstaller 制作爬虫小程序

环境:mac python3.7 pyqt5 pyinstaller ps: 主要是熟悉pyqt5, 加入了单选框 输入框 文本框 文件夹选择框及日历下拉框 效果图: pyqt5 主程序文件 # -*- coding: utf-8 -*- # Author: Mehaei # Date: 2019-07-10 13:02:56 # Last Modified by: Mehaei # Last Modified time…

axios中出现两次请求,OPTIONS请求和GET请求

在项目中发现ajax中出现两次请求&#xff0c;OPTIONS请求和GET请求 查看到浏览器NetWork有两次请求&#xff0c;请求url一样&#xff1a; 查找原因是浏览器对简单跨域请求和复杂跨域请求的处理区别。 XMLHttpRequest会遵守同源策略(same-origin policy). 也即脚本只能访问相同协…

Linux 安装 配置 Maven

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1.需要提前安装JDK&#xff0c;并且配置环境变量 请参考&#xff1a;https://blog.csdn.net/jiangyu1013/article/details/84321146 2.…

[Git高级教程 (一)] 通过 Tag 标签回退版本修复 bug

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1 前言 本系列之所以取名”Git高级教程”&#xff0c;主要是教大家解决实际工作中遇到的问题&#xff0c;要求读者会基本的Git用法和命令…

Javascript 自定义输出

缘由 前段时间再看了一些javascript的学习资料,也写的一些demo,在输出的时候一般都用alert,但这个方法会打断函数运行,用起来不是很好.还有就是console.log这个方法,这种方法原来一直以为只能在FireFox上面才能用,现在才发现主流浏览器都支持.但我的这个插件已经写的差不多了,所…

uplift model学习笔记

一、解决的问题&#xff1a; 通常的 Propensity Model 和 Response Model 只是给目标用户打了个分&#xff0c;并没有确保模型的结果可以使得活动的提升最大化&#xff1b;它没有告诉市场营销人员&#xff0c;哪个用户最有可能提升活动响应&#xff1b; 因此&#xff0c;需要另…

设计模式之依赖倒置原则

在传统的过程式中&#xff0c;上层依赖于底层&#xff0c;当底层变化&#xff0c;上层也得跟着做出相应的变化。这就是面向过程的思想&#xff0c;弊端就是导致程序的复用性降低并且提高了开发的成本。 而面向对象的开发则很好的解决了这个问题&#xff0c;让用户程序依赖于抽象…

@Transactional 详解

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Transactional 是声明式事务管理 编程中使用的注解 1 .添加位置 1&#xff09;接口实现类或接口实现方法上&#xff0c;而不是接口类中…

LiveGBS高性能GB28181国标流媒体服务流传输模式支持UDP、TCP被动、TCP主动模式

LiveGBS国标(GB28181)流媒体服务软件&#xff1a; 提供用户管理及Web可视化页面管理&#xff1b; 提供设备状态管理&#xff0c;可实时查看设备是否掉线等信息&#xff1b; 实时流媒体处理&#xff0c;PS&#xff08;TS&#xff09;转ES&#xff1b; 设备状态监测、云台控制、录…

RuntimeException 和 Exception 区别、异常的子父级关系

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1.java 将所有的错误封装为一个对象&#xff0c;其根本父类为Throwable, Throwable 有两个子类&#xff1a;Error 和 Exception。 2.Err…

C语言笔记(关键字)

gdb调试 gcc 源程序 -g&#xff1b;加gdb调试信息gdb可执行程序&#xff1b;&#xff08;gdb调试&#xff09;l&#xff08;ist&#xff09;&#xff1a;查看源码&#xff0c;按一下从main开始10行以此往后l n&#xff1a;查看n处上下10行的源码run&#xff1a;运行程序b&…

C语言笔记(符号)

注释符号 几个似非而是的注释问题 例子&#xff1a; (A) int / * ... * /i; (B) char * s "abcdefgh //hijklmn"; (C) //Is it a \valid comment? (D) in/ * ... * /t i; 我们知道C语言里可以有两种注释方式&#xff1a;“/* */” 和 “ // ”。那么上面几条…