【C++进阶】深入STL之vector:构建高效C++程序的基石

📝个人主页🌹:Eternity._
⏩收录专栏⏪:C++ “ 登神长阶 ”
🤡往期回顾🤡:模拟实现string
🌹🌹期待您的关注 🌹🌹

在这里插入图片描述

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

❀STL之vector

  • 📒1.vector类的基本概念
  • 📕2. vector类的常用操作
    • 🌈vector类对象的常见构造
    • 🌞vector类对象的容量操作
    • 🌙vector类对象的增删查改
  • 📜3. vector类的模拟实现
    • 🍁vector的成员变量
    • 🌸vector的构造函数
    • 🌷vector的析构函数
    • 🌻vector的拷贝构造函数
    • 🌼vector的运算符重载
    • 🍂vector容量相关函数
  • 📖4. 总结


学习STL中的vector:开启C++容器之旅的前言

  • 在C++的编程世界中,标准模板库(STL)无疑是每位开发者都需要熟练掌握的工具集。其中,vector作为STL中最常用的动态数组容器之一,以其灵活、高效和易用的特性,成为了众多C++程序员的首选。

vector容器允许我们存储任意数量的同类型元素,并且能够根据需要进行动态扩展。这种灵活性使得vector在处理大量数据时变得尤为高效,无论是在科学计算、图形处理、网络编程还是游戏开发等领域,我们都能看到vector的身影。
现在让我们一起踏上学习STL中vector的旅程吧!


📒1.vector类的基本概念

vector是C++标准模板库(STL)中的一个动态数组容器,它提供了对一段连续空间的动态管理功能。与普通的C++数组相比,vector具有许多优点,如可以动态调整大小、支持随机访问等

在这里插入图片描述


vector类成员函数:

class string
{
private:iterator _start;iterator _finish;iterator _end_of_storage;
};

在这里插入图片描述


📕2. vector类的常用操作

🌈vector类对象的常见构造

构造函数声明接口说明
vector()无参构造
vector(size_type n, const value_type& val = value_type())构造并初始化n个val
vector (const vector& x);拷贝构造
vector (InputIterator first, InputIterator last);使用迭代器进行初始化构造
int main()
{vector<int> v1; // 无参构造vector<int> v2(10, 0); // 构造并初始化n个valvector<int> v3(v2); // 拷贝构造vector<int> v4(v2.begin(),v2.end()); // 使用迭代器进行初始化构造return 0;
}

关于 vector iterator 的使用

iterator的使用接口说明
begin +end获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置的iterator/const_iterator
rbegin + rend获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的reverse_iterator

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

其实vector的很多用法和string类似


🌞vector类对象的容量操作

容量空间接口说明
size获取数据个数
capacity获取容量大小
empty判断是否为空
resize改变vector的size
reserve改变vector的capacity
int main()
{vector<int> v(10, 0);cout << v.size() << endl; // 获取数据个数cout << v.capacity() << endl; // 获取容量大小v.reserve(20); // 改变vector的capacitycout << endl;cout << "after reserve size: " << v.size() << endl;cout << "after reserve capacity: " << v.capacity() << endl;cout << endl;v.resize(20); // 改变vector的sizecout << "after resize size: " << v.size() << endl;cout << "after resize capacity: " << v.capacity() << endl;cout << v.empty() << endl; // 判断是否为空return 0;
}

在这里插入图片描述

注意:

  • capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL
  • reserve只负责开辟空间,不会影响size的大小,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
  • resize在开空间的同时还会进行初始化,会影响size的大小

🌙vector类对象的增删查改

vector增删查改接口说明
push_back尾插
pop_back尾删
insert在pos之前插入val
erase删除pos位置的数据
swap交换两个vector的数据空间
operator[ ]像数组一样访问

注意:find 查找,这个是算法模块实现,不是vector的成员接口
在这里插入图片描述

代码示例:

int main()
{vector<int> v1(1, 0);v1.push_back(1); // 尾插v1.push_back(2);v1.push_back(3);v1.push_back(5); // 尾插后v1 : 0,1,2,3,5v1.pop_back(); // 尾删后v1 : 0,1,2,3cout << "v1: ";for (size_t i = 0; i < v1.size(); i++) // 遍历vector数组{cout << v1[i] << " "; // operator[]随机访问}cout << endl;vector<int> v2(10, 0);cout << "v2: ";for (size_t i = 0; i < v2.size(); i++){cout << v2[i] << " ";}cout << endl;v1.swap(v2); // 交换v1,v2内容cout << "after swap v1: ";for (size_t i = 0; i < v1.size(); i++){cout << v1[i] << " ";}cout << endl;vector<int>::iterator it = find(v1.begin(), v1.end(), 0); // 查找cout << *it;return 0;
}

在这里插入图片描述


注意:insert和erase在vector里面有点特殊,在vector上它使用的都是迭代器

在这里插入图片描述

erase往往和find搭配使用

vector<int> v{1,2,3,4,5,6,7,8,9};
auto pos = find(v.begin(),v.end(),6);
v.erase(pos);//删除一个区间
v.erase(v.begin() + 1,v.end() - 1);

在这里插入图片描述

insert头插一个0

vector<int> v{1,2,3,4,5,6,7,8,9};
auto pos = v.begin();
v.insert(pos,0);

📜3. vector类的模拟实现

🍁vector的成员变量

首先我们要先搞清楚 vector的成员变量,我们清楚 vector类在底层实际上也是指针,在模拟实现 vector之前,我们创建一个属于自己的命名空间来与库里面的区分

namespace pxt
{template<class T>class vector{public:// vector的迭代器是一个原生指针typedef T* iterator;typedef const T* const_iterator;// 迭代器相关(迭代器主要就是找到头尾)iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}private:// 成员变量iterator _start; // 指向有效数据的头iterator _finish; // 指向有效数据的尾iterator _end_of_storage; // 指向最大空间的地方};
}

在这里插入图片描述

在这里插入图片描述


🌸vector的构造函数

无参构造:

vector():_start(nullptr), _finish(nullptr), _end_of_storage(nullptr)
{}

带参的构造函数

vector(size_t n, const T& val = T()):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr)
{reserve(n); // 开辟空间for (size_t i = 0; i < n; i++){push_back(val); // 给初始值赋值// reserve,push_back的模拟实现下面会讲}
}

迭代器区间构造

为了实现不同类型迭代器的构造,这里需要再创建一个模板

template <class InputIterator> // 类似与STL
vector(InputIterator first, InputIterator last):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr)
{while (first != last){push_back(*first);++first;}
}

🌷vector的析构函数

析构函数比较简单,将空间释放,各个指针置为空

~vector()
{delete[] _start;_start = _finish = _end_of_storage = nullptr;
}

🌻vector的拷贝构造函数

vector(const vector<T>& v):_start(nullptr), _finish(nullptr), _endof_storage(nullptr){reserve(v.capacity());for (const auto& e : v){push_back(e);}}

🌼vector的运算符重载

void swap(vector<T> v)
{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_end_of_storage, v._end_of_storage);
}
// 现代写法
vector<T>& operator=(vector<T> tmp){swap(tmp); return *this;}

🍂vector容量相关函数

跟容量有关的函数size,capacity,empty,resize,reverse,push_back

size_t size() const
{return _finish - _start;
}size_t capacity() const
{return _endof_storage - _start;
}bool empty() const
{return _start == _finish;
}

reverse

reverse只会改变capacity的大小,并不会改变size的大小

void reserve(size_t n)
{if (n > capacity()) // n < capacity()时,则不需要作出反应{size_t sz = size(); // 先保存以下size的值T* tmp = new T[n]; // 开辟空间if (_start){//memcpy(tmp, _start, sizeof(T)*sz);for (size_t i = 0; i < sz; ++i){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_end_of_storage = _start + n;}
}

resize

resize不仅会改变size大小,也会改变capacity大小

void resize(size_t n, const T& val = T()) // val=T()用了匿名对象
{if (n > capacity()){reserve(n); // 开辟额外空间} if (n > size()){// 初始化填值while (_finish < _start + n){*_finish = val;++_finish;}}else{_finish = _start + n;}
}

注意:C++将内置类型特殊处理过,int/char等等都被升级为了类,所以可以使用int()表示匿名对象

int main()
{cout << int() << endl; // int的缺省值为0,所以输出 0return 0;
}

push_back

void push_back(const T& x)
{if(_finish == _end_of_storage){size_t sz = size();size_t cp = capacity() == 0 ? 4 : capacity() * 2;T* tmp = new <T>(cp);if(_start){// memcpy(tmp, _start, sizeof(T) * sz);for (size_t i = 0; i < sz; ++i){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_end_of_storage = _start + cp;}*_finish = x;_finish++;
}

当探索并深入了解了STL中的vector容器后,我们不禁感叹其强大的功能和灵活性。随着对vector的学习和使用,我们逐渐理解到,一个高效的C++程序不仅仅是代码的堆砌,更是对数据结构、算法和STL等标准库深刻理解的体现。vector的迭代器、容量管理、元素访问以及算法支持等功能,都是我们在日常编程中不可或缺的工具


📖4. 总结

学习vector仅仅是开始。STL(Standard Template Library)还提供了诸如list、set、map等其他强大的容器,每个都有其独特的特点和适用场景。因此,鼓励大家继续深入学习STL,探索其背后的设计理念和实现原理。通过不断实践,我们不仅能够提高编程效率,还能够培养出更加优雅、健壮的代码风格。最后,我想说的是,学习是一个永无止境的过程。无论是STL还是其他任何技术,都值得我们不断学习和探索。让我们保持对知识的渴望和好奇心,不断前行,在编程的道路上越走越远

在这里插入图片描述
谢谢大家支持本篇到这里就结束了,祝大家天天开心!
在这里插入图片描述

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

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

相关文章

网络编程(七)

网络编程&#xff08;七&#xff09; UNIX域套接字&#xff08;本地间进程间通信的技术&#xff09;&#xff08;S文件&#xff09;基于TCP传输基于UDP传输 UNIX域套接字&#xff08;本地间进程间通信的技术&#xff09;&#xff08;S文件&#xff09; socket同样也可以用于本…

OpenCV-绘制虚线

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 功能函数 // 绘制虚线 void DrawDottedLine(cv::Mat &input, cv::Point p1, cv::Point p2, cv::Scalar color, int thickne…

Android Graphics 显示系统 - Android Jank detection with FrameTimeline

“ 最近有公司同事在处理UI卡顿及FPS自动化监测的问题&#xff0c;我也顺便看了一点相关的内容&#xff0c;其中在Perfetto的官方说明文档中有一篇关于利用FrameTimeLine进行Jank监测的解读&#xff0c;个人觉得蛮有意思的&#xff0c;借助工具翻译该篇文章并加上本人拙劣的解读…

C++系列-类模板

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 类模板的定义格式&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; template<class T> class Stack { public:Stack(size_…

【Java EE】网络原理——HTTPS

目录 1.HTTPS是什么 2.“加密”是什么 3.HTTPS的工作过程 3.1引入对称加密 3.2 引入非对称加密 4.中间人攻击 5.引入证书 6. 理解数据签名 7.通过证书解决中间人攻击 7.1 查看浏览器的授信任证书发布机构 7.2 中间人有没有可能篡改证书&#xff1f; 7.3 中间人整个掉…

latex公式输入练习

给大家提供几个公式供大家练习latex输入数学公式&#xff0c;同时也是对自己新学latex语言的一种复习吧。&#xff08;如果大家对latex输入公式感兴趣&#xff0c;推荐一下哔站视频&#xff1a;LaTeX公式保姆级教程 (以及其中的各种细节)_哔哩哔哩_bilibili&#xff09; 公式一…

基于.NetCore和ABP.VNext的项目实战七:全局异常处理并日志记录

ABP框架已经默认为我们实现了全局的异常模块,这里我们自定义全局异常模块,先在HelloWorldController中写一个异常接口,测试下ABP的默认全局异常: [HttpGet][Route("Exception")]public string Exception(){throw new NotImplementedException("这是一个未实…

Vue——监听器简单使用与注意事项

文章目录 前言编写简单demo注意事项 前言 监听器&#xff0c;在官网中称为侦听器&#xff0c;个人还是喜欢称之为监听器。官方文档如下&#xff1a; vue 官网 侦听器 编写简单demo 侦听器在项目中通常用于监听某个属性变量值的变化&#xff0c;并根据该变化做出一些处理操作。…

leetcode第263题:丑数

丑数的因子只能是2,3,5。但是可能有多个2&#xff0c;多个3&#xff0c;多个5.因此需要循环地除以2、3、5. public class Solution {public bool IsUgly(int n) {if (n < 0) {return false;}int[] factors {2, 3, 5};for ( int i0;i<3;i) {int factorfactors[i];while …

Visual C++2010学习版详细安装教程(超详细图文)

Visual C 介绍 Visual C&#xff08;简称VC&#xff09;是微软公司推出的一种集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于开发C和C语言的应用程序。它提供了强大的编辑器、编译器、调试器、库和框架支持&#xff0c;以及丰富的工具和选项&#xff0c;使得开…

【计算机-ARM】

计算机-ARM ■ 指令集■ 1. RISC■ 2. CISC ■ ARM简介■ 1.■ 2. ■ ARM-CPU体系架构■ 1. M0■ 2. M3■ 3. M4■ 4. M7■ 5. M7■ 6. M7 ■ ARM-寄存器■ 1. 通用寄存器■ 2.■ 3.■ 4. ■ ARM-工作模式■ ARM-寄存器组■ ARM-异常向量表■ 由于soc0x00000000 是存放IROM芯片…

HDL-A/1-110VAC-2电流继电器 JOSEF约瑟 导轨安装

一. 应用 HDL系列电流继电器是静态型&#xff0c;不带方向性的、瞬动、交流电流继电器。可用于电力系统输电线,电机过负荷和短路保护中&#xff0c;作为启动元件。 继电器对短路电流中的直流分量不敏感&#xff0c;因此可用于要求哲态超小的线路中&#xff0c;改继电器由集成…

基于单片机的八路抢答器设计论文

绪 论1.1 课题研究的相关背景 抢答器是一种应用非常广泛的设备,在各种竞赛、抢答场合中,它能迅速、客观地分辨出最先获得发言权的选手。早期的抢答器只由几个三极管、可控硅、发光管等组成,能通过发光管的指示辩认出选手号码。现在大多数抢答器均使用单片机(如MCS-5…

python基础-数据结构——hash表、线性探测、二重探测、双重哈希、闭散列(分离链接)(拉链法)Python代码实现

文章目录 哈希表及其碰撞解决策略1. 引言2. 哈希表简介3. 哈希函数4. 碰撞解决策略4.1 分离链接法&#xff08;拉链法&#xff09;4.2 开放寻址法4.2.1 线性探测4.2.2 二次探测4.2.3 双重哈希 5. 总结 哈希表及其碰撞解决策略 1. 引言 哈希表是一种高效的数据结构&#xff0c…

BugKu 哎,就是玩

说明&#xff1a;通过图片隐写找到迷宫压缩包解码密码&#xff0c;然后通过MG游戏得到井字棋游戏解压密码&#xff0c;最后通过完成井字棋得到flag. 打开实验包&#xff0c;解压后可以看到两个文件。 首先要通过TKR.png找到迷宫.zip的解压密码。 打开图片&#xff0c;发现图片…

【grafana】创建多变量table

这个普罗米修斯的指标啊&#xff0c;大多数都是键值对&#xff0c;而且笔者如果没记错&#xff0c;他这个值还必须是浮点。少数可以设成离散值&#xff08;Enum&#xff09;&#xff0c;但本质还是一个带翻译功能的键值对 这样的好处是&#xff0c;做起来非常简单&#xff0c;…

Websocket服务端结合内网穿透发布公网实现远程访问发送信息

文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…

计算机毕业设计hadoop+spark+hive物流快递大数据分析平台 物流预测系统 物流信息爬虫 物流大数据 机器学习 深度学习 知识图谱 大数据

1.Python爬虫采集物流数据等存入mysql和.csv文件&#xff1b; 2.使用pandasnumpy或者MapReduce对上面的数据集进行数据清洗生成最终上传到hdfs&#xff1b; 3.使用hive数据仓库完成建库建表导入.csv数据集&#xff1b; 4.使用hive之hive_sql进行离线计算&#xff0c;使用spark之…

乡村振兴的乡村环境综合整治:加强农村环境综合整治,改善农村人居环境,打造干净整洁的美丽乡村

目录 一、引言 二、农村环境问题的现状与挑战 &#xff08;一&#xff09;农村环境问题的现状 &#xff08;二&#xff09;农村环境问题的挑战 三、加强农村环境综合整治的必要性 &#xff08;一&#xff09;提升农民生活质量 &#xff08;二&#xff09;促进农村经济发…

ClickHouse 实现用户画像(标签)系统实践

文章目录 前言用户画像概述用户画像系统介绍用户画像系统的需求描述用户画像系统的需求分析用户画像系统的架构 关键技术实现&#xff08;Clickhouse SQL&#xff09;分析阶段运营阶段 基于ClickHouse的用户画像系统的优点 前言 本文介绍一个ClickHouse应用案例—用户画像系统…