草庐IT

【C++】vector类概述

命由己造~ 2023-09-06 原文

vector

一、标准库中的vector

文档链接

1.1 vector的介绍

vector可以类比C语言的数组,他就像是一个可以动态增长的数组。
本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小,vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。

1.2 vector的常用接口

1.2.1 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(5, 1);// 构造并初始化n个val
	vector<int> v3(v1);// 拷贝构造
	vector<int> v4(v1.begin(), v1.end());// 使用迭代器进行初始化构造
	return 0;
}

1.2.2 vector类对象的访问及遍历操作

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

operator[] 返回pos位置的数据

int main()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	vector<int>::iterator it = v.begin();// 正向访问
	while (it != v.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
	vector<int>::reverse_iterator rit = v.rbegin();// 逆向访问
	while (rit != v.rend())
	{
		cout << *rit << " ";
		rit++;
	}
	cout << endl;
	for (int i = 0; i < v.size(); i++)// []访问
	{
		cout << v[i] << " ";
	}
	cout << endl;
	return 0;
}

1.2.3 vector类对象的容量操作

size 获取数据个数
capacity 获取容量大小
empty 判断是否为空
reserve 扩容
resize 扩容+初始化

int main()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	cout << v.size() << endl;// 获取数据个数
	cout << v.capacity() << endl;// 获取容量大小
	cout << v.empty() << endl;// 判断是否为空
	v.reserve(10);// 扩容
	cout << "newsize:" << v.size() << endl;
	cout << "newcapacity:" << v.capacity() << endl;
	v.resize(10);// 扩容 + 初始化
	cout << "newsize:" << v.size() << endl;
	cout << "newcapacity:" << v.capacity() << endl;
	return 0;
}

结果:

4
4
0
newsize:4
newcapacity:10
newsize:10
newcapacity:10

1.2.4 vector类对象的修改操作

push_back 尾插
pop_back 尾删
assign 覆盖
find 查找(注意这个是算法模块实现,不是vector的成员接口)
sort 排序(注意这个是算法模块实现,不是vector的成员接口)
insert 在position之前插入val
erase 删除position位置的数据
swap 交换两个vector的数据空间

除了assign和find其他接口在string类的概述里面讲过,他们都大同小异。
【C++】string类概述

int main()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.assign(4, 10);// 覆盖
	for (auto e : v)
	{
		cout << e << " ";
	}
	return 0;
}


使用find和sort前要先引入库函数:#include <algorithm>

int main()
{
	vector<int> v;
	v.push_back(5);
	v.push_back(4);
	v.push_back(3);
	v.push_back(2);
	v.push_back(7);
	v.push_back(1);
	v.push_back(6);
	vector<int>::iterator it = find(v.begin(), v.end(), 6);// 查找
	cout << *it << endl;
	sort(v.begin(), v.end());// 排序
	for (auto e : v)
	{
		cout << e << " ";
	}
	return 0;
}

二、迭代器失效问题

首先要知道迭代器的底层是指针,或者是对指针进行了封装,vector的原生态指针就是T*
而迭代器失效就是指针指向的空间被销毁了,如果继续使用,就会造成崩溃。

对于vector可能会导致其迭代器失效的操作有:
引起其底层空间容量改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、assign、push_back等

例如:

int main()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		it++;
	}
	v.reserve(10);
	while (it != v.end())
	{
		cout << *it << " ";
		it++;
	}
	return 0;
}


迭代器失效解决办法:在使用前,对迭代器重新赋值即可。,后面的模拟实现会讲解。



纸上得来终觉浅,绝知此事要躬行。

有关【C++】vector类概述的更多相关文章

  1. 阿里云RDS——产品系列概述 - 2

    基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于

  2. Ruby 语言备忘单/海报/引用/概述? - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion我是一个喜欢视觉的人,想知道是否有关于Ruby的不错的大概览。你知道,就像一张引用海报,带有对象层次结构,最常用的方法等等,都是彩色的,布局清晰明了...对于像我这样的初学者来说,这会很棒......有没有你使用或偶然发现的类似东西?

  3. ruby - 为什么我不能让 swig wrap std::vector 到 Ruby 类? - 2

    我有一个带有嵌入式Ruby解释器的应用程序,以及与swig生成的STL类的接口(interface)。多亏了swig,几乎所有事情都进行得很好,除了一件事:%moduleStuff%import"std_vector.i"namespacestd{%template(Vectord)vector;};%inline%{std::vectortest;%}当我尝试在Ruby中使用它时,类型Stuff::Vectord存在,但它不是生成的单例方法测试的返回类型。查看生成的C包装器文件,我可以看到类Vectord及其方法已定义,但查看_wrap_test_get我没有看到任何返回sth类St

  4. javascript - Visual Studio 2015 Javascript 概述方式太多 - 2

    VisualStudio2015接缝勾勒出所有多行javascript代码。我有一个像这样的简单代码:$(document).ready(function(){varx={test1:1,test2:2};if(1==1){//thisisatest}});当我按下Ctrl+k,Ctrl+O时,VisualStudio2015会这样概括它:是否可以关闭函数内的大纲?我只想要功能级别的大纲。 最佳答案 不,你做不到,但有优秀的WebEssentials可以在javascript中勾勒出区域!你在像这样的评论之后创建一个区域//#reg

  5. javascript - OL3 : Zoom to vector layer on map - 2

    我有一张带有openlayers3和矢量图层的map。我想将map调整为该矢量图层的大小,但到目前为止,我所能得到的只是将map居中放置在该矢量的最后一个点上,因为在创建map时无法访问矢量图层的点:if(trackMap!=null){for(vari=0;i 最佳答案 为什么不只适合ol.source.Vector的范围?varsource=newol.source.Vector();...map.getView().fitExtent(source.getExtent(),map.getSize());

  6. javascript - 三.js : 2xMeshes using same vector as position - 2

    刚刚在ThreeJS中从r67到r69进行了更新,结果在将它们的位置引用到一个(相同的)向量时遇到了问题。在我这样做之前:varvector=newTHREE.Vector3(50,50,50);_Mesh1.position=vector;_Mesh2.position=vector;这使得当我移动其中一个网格时它也移动了另一个成为可能。在r69中,位置向量保持不变(又名0、0、0),这意味着每当我对另一个网格进行模式化时,我必须手动设置每个网格的X、Y和Z坐标。我是不是漏掉了一些零钱?或者我应该怎么做才能解决这个问题? 最佳答案

  7. javascript - 开放层 3 : how to set fill style of a vector feature - 2

    我正在尝试设置矢量图层的单独特征的填充颜色。使用下面的代码,我认为我可以遍历这些功能并单独设置它们的填充样式,但是发生了一个奇怪的问题。如果没有setStyle函数,功能的各种属性将记录在控制台中。ID、名称和几何图形。大约有5个左右的功能被记录下来。基本喜欢room1room2room3room4room5每个数据下面都有额外的数据(id、geometry)但是当我添加设置特征填充的行时,我遇到了一个奇怪的问题。它似乎在第一个功能上挂起循环,并且控制台填满了该功能属性的日志,例如:room1room1room1room1room1room1room1很长一段时间,到了firefox日

  8. javascript - 在 AngularJS 中选择下拉项时显示概述文本 - 2

    我希望显示每个小部件类别的概览,以便在选择该小部件类别时显示在过滤结果上方。我假设这将需要一个ng-show指令,因此可能也需要一些Controller代码。但是任何关于将选择下拉菜单与我的ng-repeat链接起来以及与ng-show链接起来的任何指示都会很棒。这是我的目标:之前之后SelectWidgetRange1WidgetRange2WidgetRange3ProductName:{{product.name}}Quantity:{{product.quantity}}Price:£{{product.price}}https://plnkr.co/edit/0WrinKY2

  9. C++中vector<vector<int> >的用法 - 2

    注意vector>后面的尖括号前面要加上空格,否则在有些编译器出现问题vector>A;//错误的定义方式vector>A;//正确的定义方式一、为什么是vector?对于数组,大家常用索引和指针来操作数组,给程序设计带来了很大的灵活性。但是数组的越界可能会引起程序的崩溃,而且动态性不好,包括动态改变大小,动态申请。有什么办法可以解决这些问题吗?关于vector我不想多说,我假设大家都了解temlplate和STL比如map、list、vector等)。学习C++的时候学到过STL(标准模板库)知道vector提供了operator[]函数。可以像数组一样的操作,而且还有边界检查,动态改变大小

  10. 基于AIGC的3D场景创作引擎概述 - 2

    通过改变3D场景制作流程复杂、成本高、门槛高、流动性差的现状,让商家像玩转2D一样去玩转3D,让普通消费者也能参与到3D内容创作和消费中,真正实现内容生产模式从PGC/UGC过渡到AIGC,是我们3D场景智能创作引擎一直追求的目标。前言随着元宇宙的大火,国内外各大厂纷纷下场开始为下一代互联网技术布局,旨在为用户提供更好的体验。体验包括方方面面,比如更好的游戏体验、更好的社交体验、更高效的办公体验当然也包括更好的消费体验。作为国内最大的电商平台,我们团队也在持续思考如何基于元宇宙的技术,给消费者带来更好的购物体验以及给商家带来更好的营商体验。回归到电商“人、货、场”三要素上,通过虚拟人技术以及商

随机推荐