C++中vector的简单实现

文章目录

  • 一、主要任务
    • 1. 查看文档的网站的链接
    • 2.内部模拟的函数
  • 二、本人的模拟实现过程
    • 1. 所需模拟实现的函数
      • a.构造、拷贝构造
      • b. reverse()扩容
      • c.insert()、push_back()插入数据
      • d. erase()、pop_back()删除数据
      • e. swap()交换
      • f. begin()、end()非const与const迭代器
      • g. 完善构造函数之一:多个同数值参数构造
      • h. 完善构造函数之二:拷贝构造
      • i. 完善构造函数之三:迭代区间构造
      • j. 完善构造函数之四:初始化列表构造
      • k. 赋值重载
      • l. size()数据有效个数
      • m. resize()调整数据有效个数
      • n. operator[]()运算符重载
      • o. 析构函数
    • 2.内置类型声明
    • 3. 基础无参构造函数实现
    • 4. insert()插入
    • 5. capacity()计算容量
    • 6. reverse()扩容
    • 7. push_back()尾插
    • ※简单1-7 test()测试
    • 8. erase()删除
    • 9. pop_back()尾删
    • 10. swap()交换
    • 11. begin()、end()非const与const迭代器
    • ※测试iterator迭代器const与非const
    • 12.多个同数值构造
    • 13. 拷贝构造
    • 14. 迭代区间构造
    • 15. 初始化列表构造
    • 16. operator=()赋值重载
    • 17.size()有效数据个数
    • 18. resize()调整数据有效个数
    • 19.operator[]运算符重载
    • 20. 析构函数
    • ※[]与resize简单测试
  • 总结

一、主要任务

1. 查看文档的网站的链接

cplusplus网站
cppreference网站

2.内部模拟的函数


namespace myvector
{
  template<class T>
  class vector
  {
  public:
    // Vector的迭代器是一个原生指针
    typedef T* iterator;
    typedef const T* const_iterator;

    iterator begin();
    iterator end();
    const_iterator cbegin();
    const_iterator cend() const// construct and destroy
    vector()vector(int n, const T& value = T())template<class InputIterator>
    vector(InputIterator first, InputIterator last)vector(const vector<T>& v);
    vector<T>& operator= (vector<T> v)~vector()// capacity
    size_t size() const ;
    size_t capacity() constvoid reserve(size_t n)void resize(size_t n, const T& value = T())///access///
    T& operator[](size_t pos)const T& operator[](size_t pos)const///modify/
    void push_back(const T& x)void pop_back()void swap(vector<T>& v);
    iterator insert(iterator pos, const T& x);
    iterator erase(Iterator pos)private:
    iterator _start; // 指向数据块的开始
    iterator _finish; // 指向有效数据的尾
    iterator _endOfStorage; // 指向存储容量的尾
  };

}
主要实现的函数有几个模块,分别为:
1、构造析构
2、容量大小与扩容
3、运算符重载
4、插入删除
5、迭代器
(这里直接使用迭代器来访问了,这里简单实现的迭代器就是原生指针)

二、本人的模拟实现过程

这里可以去看文档使用与模拟实现,有些缺省参数啥的我这就不实现了
有些缺省参数没学之前可以直接不用

1. 所需模拟实现的函数

用红色框框起来

a.构造、拷贝构造

在这里插入图片描述

b. reverse()扩容

在这里插入图片描述

reverse()扩容只需要传一个参数,,这个参数可能是最后的容量
在这里,扩容会有两种情况:
1、n > _endOfStorage就需要扩容(_endOfStorage是指向所开辟的总空间的最后一个的下一个位置)
(这里是指针,指向的确实是最后的下一个位置的空间如同capacity)
2、 n <= _endOfStorage就什么都不做,总容量不变,该函数不缩容

c.insert()、push_back()插入数据

在这里插入图片描述

(1)在position位置插入一个数据
(2)在position位置插入n个数据
(3)在position位置向后插入一段迭代区间
(4)不会玩
(5)插入一个initializer_list对象(常见的是这种:{value1, value2, ....})

在这里插入图片描述

这里push_back()重载成两个,我这只实现第一个
第一个和第二个的区别是后面的形参中是否带了const
但以我们习惯,插入的时候是不需要修改要插入的数据的
并且以外层来看,const对象也无法插入数据

d. erase()、pop_back()删除数据

在这里插入图片描述

erase()是用来删除数据的
第一个是删除position位置的数据
第二个是删除first到last的一段空间,删除范围为:[first, last)
我这简单实现第一个方法吧,主要都是挪动数据,第二个方法只要计算好从哪个挪动到哪个就好了

在这里插入图片描述

pop_back()删除最后一个数据
最后一个数据的位置就是类内置属性_finish的前一个位置

e. swap()交换

在这里插入图片描述

swap交换两个对象的内容
我们这里是以迭代器实现指向(本质也是指针)
这里的交换可以直接交换两个对象里面的属性的指向就好了
(如这里_start, _finish, _endOfStorage就是属性)

f. begin()、end()非const与const迭代器

在这里插入图片描述
在这里插入图片描述

begin()与end()是用来初始化迭代器或者给迭代器赋值的
有了begin()与end()方法,这里就可以使用迭代器变量了
另外,有了begin与end就可以使用范围for了,范围for底层是迭代器,不需要自己实现,编译器会自动转换
const与非const的区别就是无法修改内容而已,代码实现相似

g. 完善构造函数之一:多个同数值参数构造

在这里插入图片描述

这里是n个value构造一个对象

h. 完善构造函数之二:拷贝构造

在这里插入图片描述

拷贝构造是:使用已经存在的对象初始化另一个对象

i. 完善构造函数之三:迭代区间构造

在这里插入图片描述

迭代区间构造:使用其他对象的迭代区间来构造该对象
(这里挺有意思的,可以使用其他类对象的迭代区间构造)

j. 完善构造函数之四:初始化列表构造

在这里插入图片描述

初始化列表构造,初始化列表例如:{ 1,2,3,4 }这种的
使用也有两种方式:
1、vector<int> v1 = { 1,2,3,4 };
2、vector<int> v2({ 1,2,3,4 });
这样子也挺方便使用的

k. 赋值重载

在这里插入图片描述

赋值重载函数,上面图片的这里不重载,这里玩个新的
赋值重载如果使用const&则需要做扩容什么的,这里让编译器做

l. size()数据有效个数

在这里插入图片描述

很简单的函数,返回有效数据个数

m. resize()调整数据有效个数

在这里插入图片描述

实现第二个,能把空间初始化,第一个只是能扩大有效数据个数,但是里面的值可能是随机值
这里的n和string里的n是一样的功能:
(这里我把_finish - _start说成size吧,这也是有效数据个数)
(并且把_endOfStorage - _start 说成容量capacity)
1、如果n == size,则什么都不做
2、如果n < size,则把_finish调整到n位置(有效数据个数减小)
3、如果n > size && n <= capacity ,则把_finish调整到n位置,并且把旧_finish到新_finish的空间用value填充
4、如果n > capacity ,则扩容,并且把_finish调整到n位置,调整过来的空间也用value填充
(理论成立,实践开始)

n. operator运算符重载

在这里插入图片描述

重载[]是因为要下标访问,本来就是连续空间,还不能下标访问就扯蛋了
const对应const对象,非const对应普通对象,重载成两份

o. 析构函数

在这里插入图片描述

析构函数,对象生命周期结束自动调用
这里主要是释放空间,把申请的空间delete了

2.内置类型声明

在这里插入图片描述

这里的内置类型的typedef出来的指针
主要是:
1、类模版
2、模版类型指针typedef重命名为迭代器
3、迭代器管理数据的开始、结束和容量的末尾(本质也是管理指针)
(这里使用类模版主要是兼容各内置类型与自定义类型,编译器自动判别类型)

3. 基础无参构造函数实现

在这里插入图片描述

无参构造函数可以不实现,编译器会自动生成,但不同编译器可能不会初始化
这里使用了初始化列表,也可以在构造函数内赋值

4. insert()插入

在这里插入图片描述

这里我假设有revers()扩容函数和capacity()计算总容量的函数
这里主要流程思路是:
1、断言pos,不让pos是一个越界指针
2、判断_finish是否到尾了,容量是否不够了
	a. 不够容量,扩容,扩容机制是两倍,如果本来就为空就开始4个空间
		扩容之前得计算pos到_start的距离,以便扩容之后更新pos
	b. 容量足够,继续下一步
3、定义一个指针来遍历移动数据,我这里是前一个数据移到当前位置,有兴趣可以做当前位置数据移到下一个位置
4、pos位置直接插入需要插入的数据
5、插入了数据_finish向后走一步
6、返回插入数据的位置的迭代器,主要是外面使用时需要更新迭代器

5. capacity()计算容量

在这里插入图片描述

这里capacity()就是为了计算总容量的,返回的是非负数(无符号整型)
咋计算剩余容量?在外部就是调用capacity() - size()不就可以了嘛
在内部就_endOfStorage - _finish,但通常是判断_endOfStorage == _finish
(这里使用const修饰是因为能方便const与非const对象使用)

6. reverse()扩容

在这里插入图片描述

reserve()主要做扩容,判断传参的n与总容量对比,n > capacity()就扩容
主要流程思维:
1、判断是否扩容(可以复用capacity()函数来判断)
	a. 不需要扩容,直接不运行if里面了
	b. 需要扩容,进入if执行语句
2、扩容前计算之前的有效数据个数(后面需要更新指针)
3、定义新变量接收申请空间
4、旧空间的数据循环赋值给新的空间
5、释放旧空间(内存泄漏问题很严重的啊)
6、_start指向新空间,_finish根据之前旧的数据个数指向新空间的有效数据个数末尾,_endOfStorage根据开的空间指向新空间
(这里如果不记录旧的空间有效数据个数,那么后面跟新_finish就会出问题,如果不更新,后面访问就找不到_finish)

我们这里清晰的看到注释了memcpy的内存字节拷贝函数,为啥呢?
因为内置类型可以,但vector也支持内置类型

例如:
vector<string> v; 这种样子的

在这里插入图片描述

memcpy()的拷贝就是让里面的指针指向了string那片空间
接下来的delete[],string对象会调用自己的析构,但tmp还指向那片string对象空间
等到最后vector对象也析构的时候对已经释放的空间进行第二次析构释放就会出问题

所以,以上代码中是使用赋值,赋值是最简单的方法了
为啥赋值能过?
因为string类里有自己的赋值重载,一个存在的对象对另一个对象进行赋值不影响该对象的结构

7. push_back()尾插

在这里插入图片描述

push_back()可以直接复用insert()方法
insert()是在迭代器位置插入数据,而最后一个位置是_finish管理的
(也是指针,_finish指向最后一个数据的下一个位置)

※简单1-7 test()测试

在这里插入图片描述
在这里插入图片描述

因为insert()还没有迭代器的的遍历就没有测试
insert()可以简单的用push_back()简单测试
reverse()是扩容,在插入的时候自动扩容,搭配类构造函数看能不能正常扩容

以上运行可以看出,从开始3个容量,插入的时候扩两倍
4个数据输入,3+4已经超过6个了,再次两倍扩容
根据这些可以看出扩容时正常的,数据最后位置插入正常

8. erase()删除

在这里插入图片描述

erase()删除pos位置数据,这里使用覆盖的方式
主要思想流程:
1、断言判断pos是否合法
2、定义另外一个迭代器,用于遍历覆盖
3、循环判断,这里使用后一个覆盖前一个
4、_finish减1,最后返回pos的位置以便于更新迭代器

9. pop_back()尾删

在这里插入图片描述

直接复用erase()方法
假设有一个方法end()是返回最后一个数据的下一个位置的迭代器
让这位置减1并让erase()执行删除
(当然也可以直接传_finish - 1,也可以直接 --_finish)

10. swap()交换

在这里插入图片描述

这里swap()交换主要是对象里属性的内容交换
一个指针的内容交换了,逻辑上指向也交换了
这里调用的是库中的swap()方法,简单交换可以这样子用挺好的

11. begin()、end()非const与const迭代器

在这里插入图片描述

主要思维不难
因为底层的属性也是迭代器iterator定义的,而iterator是用T*定义的,一层套一层
所以我知道,只需要返回指向数据的开始和指向数据的结束的迭代器就好了
这里哪怕没有实现什么++/--啥的也能用,底层不过是指针++/--而已
(注意,这里是使用原生指针实现,但stl库不是)

※测试iterator迭代器const与非const

在这里插入图片描述

这里范围for可以直接使用,因为类内部存在begin与end方法
(使用范围for类里面必须是begin与end名字,编译器只认这两个方法)
上面是两种迭代器的用法
(个人使用迭代器简单测试了,insert与erase方法是没问题的)

12.多个同数值构造

在这里插入图片描述

使用n个value构造对象
这里可以看到两个参数,一个是n,一个是const T& value
第一个容易理解,第二个不是那么容易理解
这里的T()是类型的默认构造形成的匿名对象,会有不理解内置类型(如整型)的怎么会有默认构造
这是C++为了方便通用,类是一个类型,类定义是一个对象,内置类型是类型,内置类型定义也成为了一个对象
如果是一个自定义类型,如vector<Date>,传进来前面的const T&就是类型(这里对象实例化的时候T已经出来了)
后面的T()调用了默认构造,也就是一个空对象,这时下面的赋值也不会出问题

假如是vector<int>这种内置类型,是n个value构造对象并且不传第二个参数
如果没有自适应T()无法生成int对象(变量),那么value的值就不匹配,后面就没办法执行
所以这里的T()是能完成自定义类型与内置类型的默认构造的,内置类型也有默认构造了
主要思维流程:
1、复用reserve()方法,使用n给正在初始化的对象扩容
2、使用循环,复用push_back()方法直接尾插(因为不会改变value的值)
(因为在扩容的时候_endOfStorage已经指向后面,并且在push_back()的时候_finish已经走了,所以这都不用改变了)

13. 拷贝构造

在这里插入图片描述

主要思维流程:
1、使用人家的capacit()容量方法扩容
2、使用范围for遍历传进来的对象,并让每个内容push_back()在要实例化的对象
(因为push_bakc()不会改变传进来的实参)

14. 迭代区间构造

在这里插入图片描述

迭代区间如果不是定义赋值出问题,迭代区间不会出什么大问题
那里的函数模版,是因为不能确定是哪个类的迭代器,可以根据不同的类的迭代器生成不会的构造函数
这迭代区间初始化可以使用其他类对象的迭代区间,如这里是vector<int>的,可以给list<int>的迭代区间赋值

15. 初始化列表构造

在这里插入图片描述
在这里插入图片描述

初始列表这里比较特殊,可以查看手册
假设是vector<int> v1 = { 1,2,3,4,5 };
这里的括号就会经过隐式类型转换变成initializer_list
到里面的构造函数,因为initializer_list是一个类,形参是类对象
它也有它的迭代器,这个类挺方便的

16. operator=()赋值重载

在这里插入图片描述

看形参列表,因为是传值传参,编译器自动调用拷贝构造生成v
因为是走了拷贝构造,形参变化不改变实参,这里让形参和对象交换内容
那么,这里属性指向内容就发生了改变
返回的也是等号的右参数
出了作用域,v生命周期结束,自动调用它的析构

17.size()有效数据个数

在这里插入图片描述

有效个数就是_start到_finish之间的空间个数
因为在迭代器不飘的情况下_finish永远要大于等于_start
使用const修饰也是为了const对象与非const对象都能使用
(因为如果没有const,则const对象无法使用该方法,多写一个又没什么大作用,也没有修改)

18. resize()调整数据有效个数

在这里插入图片描述

我这里手搓的思维分为n == size、n > size、n < szie
1、n == size我什么都不做,直接返回
2、n > size
	a. 我不知道会不会超出我的容量,但我reverse方法里面有判断,所以我直接交给reverse扩容
	b. 扩不扩容我都在_start到n位置做个标记位,以便我插入数据能走到那停
	(因为push_back()方法里面会自动走_finish,所以我不用自己手动走)
3、n < szie,直接把_finish调整到n的位置,也不用覆盖,_finish就是有效个数的限制
(这里以及上面说跳到n位置,连续的空间的指针可以当成数组来使用)

19.operator[]运算符重载

在这里插入图片描述

这里[]运算符重载,是为了下标访问
const修饰是为了对应const对象,另外一个就是普通对象的重载
这里思路很简单:
1、断言限制下标合法性
2、_start可以当成数组首元素地址,可以直接当数组使用,也可以*(_start + pos);

20. 析构函数

在这里插入图片描述

这里主要是释放申请的空间
因为_start指向申请的空间的第一个位置,所以直接delete[] _start就好了
最后让三个迭代器指向空,虽然对象不存在也无法再使用到他们了,但为了规范性

※[]与resize简单测试

在这里插入图片描述

可以看到[]运算符重载是能正常运行的,并且resize也能正常的扩容与缩小
默认值value填充也正常

总结

多用就会了,手搓理解就更深,因为这是一边写代码一边写博客的,可能展示上不是很好
但这里是我一边理解一边描述的
加油吧,少年
在这里插入图片描述

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

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

相关文章

【ARM 嵌入式 C 入门及渐进 16.1 -- C 代码实现CRC32校验函数】

请阅读【嵌入式开发学习必备专栏】 文章目录 CRC32校验函数CRC32 表与函数CRC32 测试函数测试结果 对比测试结果 CRC32校验函数 在C语言中&#xff0c;实现CRC32计算的函数需要一个CRC算法的实现。以下是一个使用查表法实现CRC32的简单例子。这种方法通过预先计算好的CRC表来快…

六级翻译笔记

理解加表达 除了专有名词不能自己理解翻译&#xff0c;其它都可以 时态一般唯一 题目里出现有翻译为 客观存在&#xff1a; there be 单词结尾加er和ee的区别&#xff1a;er是主动&#xff0c;ee是被动 中文句子没有被动&#xff0c;也可以英文翻译为被动 中文的状语可以不是…

python代码实现TF-IDF

1、TF-IDF解释 TF-IDF&#xff08;Term frequency–inverse document frequency&#xff09;&#xff0c;中文翻译就是词频 - 逆文档频率&#xff0c;是一种用来计算关键词的传统方法。 TF&#xff08;Term Frequency&#xff09;&#xff1a;TF 的意思就是词频&#xff0c;是…

图片批量管理迈入智能新时代:一键输入关键词,自动生成并保存惊艳图片,轻松开启创意之旅!

在数字化时代&#xff0c;图片已成为我们表达创意、记录生活、传递信息的重要工具。然而&#xff0c;随着图片数量的不断增加&#xff0c;如何高效、便捷地管理这些图片&#xff0c;却成为了一个令人头疼的问题。 第一步&#xff0c;进入首助编辑高手主页面&#xff0c;在上方…

Vagrant + docker搭建Jenkins 部署环境

有人问&#xff0c;为什么要用Jenkins&#xff1f;我说下我以前开发的痛点&#xff0c;在一些中小型企业&#xff0c;每次开发一个项目完成后&#xff0c;需要打包部署&#xff0c;可能没有专门的运维人员&#xff0c;只能开发人员去把项目打成一个war包&#xff0c;可能这个项…

(动画详解)LeetCode面试题 02.04.分割链表

&#x1f496;&#x1f496;&#x1f496;欢迎来到我的博客&#xff0c;我是anmory&#x1f496;&#x1f496;&#x1f496; 又和大家见面了 欢迎来到动画详解LeetCode系列 用通俗易懂的动画的动画使leetcode算法题可视化 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读…

3D 生成重建010-SyncDreamer从单视图生成一致性的多视图

3D 生成重建010-SyncDreamer从单视图生成一致性的多视图 文章目录 0论文工作1论文方法2 效果 0论文工作 在zero123中&#xff0c;首先探索了给2d图像扩散模型注3d空间感知能力。可以将原图输入模型&#xff0c;通过相机位置的相对偏移生成对应的新视图。 这篇论文就是在zero1…

PAD如何实现在用RJ45上网的同时还能保证PAD的续航?|边充电边上网

在数字化时代&#xff0c;手机已经成为我们生活、工作的得力助手。当提及手机边上网边充电时&#xff0c;或许您会想&#xff1a;“这不是常态吗&#xff1f;”但今天&#xff0c;我们要探讨的是一个更为特殊而重要的场景——有线网络直连手机。对于那些需要稳定网络连接、不能…

51输出周期为40ms的方波(C+汇编)

题目 已知Fosc12MHz&#xff0c;T1工作于方式1&#xff0c; ①&#xff1a;实现20ms延时&#xff0c;求定时器初值TH0&#xff1f;TL0&#xff1f;写出具体的计算过程。 ②&#xff1a;利用汇编或C语言编程实现输出周期为40ms的方波。 周期为40ms的方波&#xff0c;半周期就…

weblogic 反序列化 CVE-2018-2628

这个漏洞因为java版本问题一直下载不了ysoserial反序列化工具&#xff0c;没办法生成payload。这里记录一下漏洞原理。 一、漏洞简介 Weblogic Server中的RMI 通信使用T3协议在Weblogic Server和其它Java程序&#xff08;客户端或者其它Weblogic Server实例&#xff09;之间传…

四川景源畅信:小白做抖音电商怎么样?

在数字时代&#xff0c;抖音已成为一个不可忽视的电商平台。对于初入行的小白来说&#xff0c;涉足抖音电商似乎既充满机遇又伴随着挑战。要判断小白做抖音电商的可行性&#xff0c;我们不妨从几个关键方面进行深入探讨。 一、市场趋势与流量获取 抖音作为新媒体的代表之一&…

2-1 EXTI外部中断(gd32)

中断的概念 中断硬件结构/软件结构 EXTI中断 EXTI硬件结构 注&#xff1a;EXTI线在同一时刻只能连接一个GPIO口&#xff0c;如果我们先连接了PA0,然后又连接了PB0那么此时PA0这个IO口就失去作用。 中断触发函数 中断优先级 中断优先级 数值越小优先级越高&#xff0c;抢占优先级…

[AutoSar]BSW_Diagnostic_004 ReadDataByIdentifier(0x22)的配置和实现

目录 关键词平台说明背景一、配置DcmDspDataInfos二、配置DcmDspDatas三、创建DcmDspDidInfos四、创建DcmDspDids五、总览六、创建一个ASWC七、mapping DCM port八、打开davinci developer&#xff0c;创建runnabl九、生成代码 关键词 嵌入式、C语言、autosar、OS、BSW、UDS、…

【HCIP学习】BGP选路、过滤及属性

一、BGP路由选路原则&#xff08;13条&#xff09; 1、首先丢弃下一跳&#xff08;NEXT_HOP&#xff09;不可达的路由&#xff1b; 2、优选Preferred-value值最大的路由&#xff1b;默认为0&#xff1b; Preferred-value&#xff1a;定义&#xff1a;首选项。 属性值&#…

5. 简单说一说uniapp中的语法吧

前言 如果你 知道Vue3并且对Vue3的语法有一定了解&#xff0c;请跳过这一章&#xff0c;由于后续项目主要是基于Vue3TypeScript&#xff0c;因此提前简单概述一些Vue3的基础语法~ 本文的目的是 期望通过对本文的阅读后能对Vue3的每个语法有一个简单的印象&#xff0c;至少要知…

Android 13 系统自定义安全水印

效果 源码实现 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java public final void showSafeModeOverlay() {View v LayoutInflater.from(mContext).inflate(com.android.internal.R.layout.safe_mode, null);WindowManager.Layout…

《C++学习笔记---初阶篇6》---string类 上

目录 1. 为什么要学习string类 1.1 C语言中的字符串 2. 标准库中的string类 2.1 string类(了解) 2.2 string类的常用接口说明 2.2.1. string类对象的常见构造 2.2.2. string类对象的容量操作 2.2.3.再次探讨reserve与resize 2.2.4.string类对象的访问及遍历操作 2.2.5…

宝塔面板怎么解决nginx跨域问题

1.找到宝塔的nginx配置文件 宝塔有一点不同&#xff0c;nginx配置文件不在nginx的安装目录中&#xff0c;应当去/www/server/panel/vhost/nginx找到 2.添加你要跨域的地址 location /api {proxy_pass http://localhost:8080;proxy_set_header Host $host;proxy_set_header X-…

爱普生推出5G基站可用耐高温高稳定性温补晶振

爱普生推出了六款新的温补晶振型号:TG7050CKN&#xff0c;TG7050SKNTG7050CMN&#xff0c;TG7050SMN&#xff0c;TG-5510CA&#xff0c;TG-5511CA。这几款的特点就是耐高温温度可达105℃C高温&#xff0c;而且都是高稳定性温补晶振&#xff0c;而且都是7050尺寸&#xff0c;这个…

map 和 set 的介绍和简单使用

目录 1. 序列式容器和关联式容器 2. 键值对 2.1. make_pair 3. 树形结构的关联式容器 3.1. set (Key 模型) 3.1.1. std::set::find 和 std::set::count 3.2. map (Key-Value 模型) 3.2.1. std::map::insert 3.2.2. std::map::operator[] 3.3. multiset 3.4.1. std::…