从构造到操作:全面掌握 C++ std::vector 的接口使用

从构造到操作:全面掌握 C++ std::vector 的接口使用

一、vector的接口

在这里插入图片描述

vector是一个类模板,这也就意味着可以存储各种类型。vector底层是一个数组,一个顺序容器

接下来就看看vector的接口。

1. 构造函数

//用n个val构造vector对象explicitvector(size_type n,const value_type& val =value_type(),const allocator_type& alloc =allocator_type());//用一段迭代器区间构造vector对象template<classInputIterator>vector(InputIterator first, InputIterator last,const allocator_type& alloc =allocator_type());//拷贝构造vector(const vector& x);
在这里插入图片描述

2. 赋值运算符重载

//用一个vector对象赋值给另一个vector对象 vector&operator=(const vector& x);
在这里插入图片描述

3. 迭代器

//分为普通迭代器,const版本迭代器,反向迭代器//begin指向空间的起始位置 iterator begin(); const_iterator begin()const;//end指向尾后位置 iterator end(); const_iterator end()const;//反向迭代器,rbegin指向末尾 reverse_iterator rbegin(); const_reverse_iterator rbegin()const;//rend指向空间起始位置的前一个位置 reverse_iterator rend(); const_reverse_iterator rend()const;
在这里插入图片描述


在这里插入图片描述

4. 容量

//返回vector中元素的个数 size_type size()const;//n < size(),保留前n个元素,其余删除//n > size(), 插入元素到n个数据//n > capacity(),会扩容voidresize(size_type n, value_type val =value_type());//vector的容量 size_type capacity()const;//判空boolempty()constnoexcept;//n > capacity(),申请空间到n个或者更大//其它情况,不会申请空间,vector的容量没有影响voidreserve(size_type n);//缩容,请求容器的容量适应size的大小(不一定等于size,可能会大于)voidshrink_to_fit();
在这里插入图片描述

5. 访问元素

//访问n位置上的元素,并返回其引用 reference operator[](size_type n); const_reference operator[](size_type n)const;//访问第一个元素 reference front(); const_reference front()const;//访问最后一个元素 reference back(); const_reference back()const;
在这里插入图片描述

6. 修改

//赋值,用一个vector的内容去代替当前的内容,修改它的sizetemplate<classInputIterator>//用一段迭代器区间去赋值voidassign(InputIterator first, InputIterator last);//用n个val去赋值voidassign(size_type n,const value_type& val);//用初始化列表去赋值voidassign(initializer_list<value_type> il);

那么,什么才是初始化列表呢

在这里插入图片描述

初始化列表也是C++库里面的一个类模板。它的构造函数包含一个 initializer_list() noexcept ,还有3个成员函数

//返回初始化列表中的元素个数 size_t size()constnoexcept;//返回初始化列表中第一个元素的指针const T*begin()constnoexcept;//返回初始化列表最后一个元素后一个位置的指针const T*end()constnoexcept;
在这里插入图片描述
//尾插voidpush_back(const value_type& val);//尾删voidpop_back();//在pos位置之前插入元素 iterator insert(const_iterator position,const value_type& val);//在pos位置插入n个元素 iterator insert(const_iterator position,size_type n,const value_type& val);//在pos位置插入一段迭代器区间template<classInputIterator> iterator insert(const_iterator position,InputIterator first, InputIterator last);//在pos位置插入一个初始化列表 iterator insert(const_iterator position,initializer_list<value_type> il);//删除单个元素或者一段迭代器区间的元素 iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last);//交换两个vector对象的内容voidswap(vector& x);//删除所有的元素voidclear()noexcept;
在这里插入图片描述

7. 友元函数

//比较两个vector对象的大小,逐元素进行比较,如果vector的size相等并且所有元素相等,那就 == ,如果所有的元素相等,但size不相等,size大的vector大。(1)template<classT,classAlloc>booloperator==(const vector<T,Alloc>& lhs,const vector<T,Alloc>& rhs);(2)template<classT,classAlloc>booloperator!=(const vector<T,Alloc>& lhs,const vector<T,Alloc>& rhs);(3)template<classT,classAlloc>booloperator<(const vector<T,Alloc>& lhs,const vector<T,Alloc>& rhs);(4)template<classT,classAlloc>booloperator<=(const vector<T,Alloc>& lhs,const vector<T,Alloc>& rhs);(5)template<classT,classAlloc>booloperator>(const vector<T,Alloc>& lhs,const vector<T,Alloc>& rhs);(6)template<classT,classAlloc>booloperator>=(const vector<T,Alloc>& lhs,const vector<T,Alloc>& rhs);
在这里插入图片描述

8. 如何理解C++中的二维数组,如何使用C语言动态开辟二维数组?

迭代器也是有类型的可以观察到在insert函数中,使用了模板模板参数是InputIterator,其实迭代器还有种类

在这里插入图片描述

Input、Output代表输入输出Forward代表单向迭代器,Bidirectional代表双向迭代器,Random Access代表随机迭代器

那么,这些迭代器有什么区别呢

Forward只支持++操作,Bidirectional支持++,--操作,Random Access支持++,--,+,-操作

那为什么有这么多的迭代器类型呢

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

可以看到,有些函数要求传递单向迭代器,有的需要双向迭代器,有的需要随机迭代器。所以,需要不同的迭代器类型

能够传递单向迭代器的函数也能够传递双向迭代器,当然也能够传随机迭代器因为单向迭代器支持的++操作,其它迭代器也支持呀,同理,传双向迭代器的函数也能够传随机迭代器

看到这里,大家对于vector已经有了一定的了解了。那么,在C语言中,有一维数组,二维数组,在C++中呢

我们知道vector的底层是一个数组,那么,如何用C++的方式去表示一个二维数组呢?很简单,vector<vector<T>>就可以表示了。其中T是模板参数

该如何理解呢?

假设vector中的成员变量以下几个

template<classT>classvector{private: T* _start;//空间的起始地址 size_t _size;//存储元素的个数 size_t _capacity;//空间的容量};

假设存储的是整型数据,那么vector<vector<int>>就是这样子的,用图来理解一下吧。

在这里插入图片描述

这不就是一个二维数组吗用下标+[]访问的时候其实就是调用了两次operator[]运算符重载函数

vector<vector<int>> vv;//定义一个vv对象1.vv[i][j]就可以访问对应位置的数据了,和C语言访问二维数组 的方式是一样的,但是底层原理是不一样的。 2.C++访问二维数组是调用了两次operator[]运算符重载函数,第 一次调用,返回的是一个vector<int>对象的引用,第二次是由这 个返回值调用运算符重载函数的,返回二维数组里的数据。 3.C语言访问二维数组的方式其实就是一次解引用,因为二维数组其实在逻辑上就是一维数组,地址空间是连续的,所以只需要用空间的起始地址+偏移量再解引用即可。 

那么如何用C语言的方式动态开辟一个二维数组呢

在这里插入图片描述

那么,使用动态开辟的二维数组,访问数据时又是怎么理解原理呢

其实是通过两次解引用的方式访问数据的,第一次解引用访问的是一个指针,该指针指向一段数组空间,第二次也是通过(起始地址+偏移量)的方式解引用访问到数据的

Read more

掌控消息全链路(4)——RabbitMQ/Spring-AMQP高级特性详解之事务与消息分发

掌控消息全链路(4)——RabbitMQ/Spring-AMQP高级特性详解之事务与消息分发

🔥我的主页:九转苍翎⭐️个人专栏:《Java SE》《Java集合框架系统精讲》《MySQL高手之路:从基础到高阶》《计算机网络》《Java工程师核心能力体系构建》《RabbitMQ理论与实践》天行健,君子以自强不息。 1.事务 AMQP(高级消息队列协议)实现了事务机制,主要用于确保消息的原子性发布和确认。换言之,它允许你将多个操作(如发送消息、确认消息)绑定在一起,要么全部成功,要么全部失败 发送消息 @RestController@RequestMapping("/producer")publicclassProducerController{@Resource(name ="transRabbitTemplate")privateRabbitTemplate transRabbitTemplate;@Transactional@RequestMapping("/trans")publicStringtrans(){ transRabbitTemplate.convertAndSend(""

By Ne0inhk
深入浅出 MVCC —— 从零理解 MySQL 并发控制

深入浅出 MVCC —— 从零理解 MySQL 并发控制

本文面向初学者,从最基础的概念讲起,一步步带你理解 MySQL 中 MVCC(多版本并发控制)的工作原理。不需要任何前置知识,看完就能在面试中讲清楚 MVCC。 希望能对大家有帮助! 一、为什么需要 MVCC?从一个故事说起 1.1 没有并发控制的世界 想象一个银行账户系统,张三的账户余额是 1000 元。 场景一:同时读写 时刻线程A(转账)线程B(查询)T1读取余额:1000T2读取余额:1000T3扣款200,更新为800T4显示余额:1000(旧值!) 线程B看到了一个"过时"的数据。这叫做脏读或不可重复读问题。 场景二:同时写 时刻线程A(转入500)线程B(扣款200)T1读取余额:1000T2读取余额:1000T31000+

By Ne0inhk
Flutter 组件 codeable_cli 适配鸿蒙 HarmonyOS 实战:高性能命令行工具,构建交互式终端与研发脚本脚手架治理架构

Flutter 组件 codeable_cli 适配鸿蒙 HarmonyOS 实战:高性能命令行工具,构建交互式终端与研发脚本脚手架治理架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 codeable_cli 适配鸿蒙 HarmonyOS 实战:高性能命令行工具,构建交互式终端与研发脚本脚手架治理架构 前言 在鸿蒙(OpenHarmony)生态迈向工业化研发协同、涉及极高频率的代码模板生成、复杂的跨端环境自动检测及全流程自动化脚本治理的背景下,如何实现一套既能提供极致终端交互体验、又能保障跨平台(Windows/macOS/Linux)执行一致性且具备强类型命令解析能力的“CLI 开发基座”,已成为决定研发团队效能上限与工具链健壮性的关键。在鸿蒙项目涉及大量 HAP/HSP 目录结构自动维护与 OHOS SDK 路径自动寻找的场景下,如果研发工具依然依赖脆弱且难以调试的 Bash 或 Python 脚本,由于由于环境路径的微差异,极易由于由于“脚本解析冲突”导致鸿蒙应用在初始化或构建环节发生各种由于由于莫名其妙的阻塞。 我们需要一种能够解耦命令定义与执行逻辑、支持交互式问答(Prompts)且具备原生 Dart

By Ne0inhk
一文通关 MySQL 数据类型,打好高性能数据库的第一战!

一文通关 MySQL 数据类型,打好高性能数据库的第一战!

🔥海棠蚀omo:个人主页                 ❄️个人专栏:《初识数据结构》,《C++:从入门到实践》,《Linux:从零基础到实践》,《Linux网络:从不懂到不会》,《MySQL:新手入门指南》                 ✨追光的人,终会光芒万丈 博主简介: 目录 一.数值类型 1.1tinyint类型 1.2bit类型 二.小数类型 2.1float类型 2.2decimal类型 三.字符串类型 3.1char类型 3.2varchar类型 3.3char和varchar的比较 四.日期和时间类型 五.enum和set 5.1查询set中的数据 前言: 在上一篇文章中,我们学习了库和表的相关操作,而在我们上一篇的讲解中,我们提到了在列名后面跟的是数据类型,但是对于MySQL中的数据类型我们现在还一知半解,那么今天这篇文章我们就来详细谈一谈MySQL中的数据类型。 那么在详细讲解每种数据类型之前,

By Ne0inhk