栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

vector的常见接口介绍

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

vector的常见接口介绍

文章目录
  • 前言
  • vector介绍文档
  • vector内部的重命名
  • vector的构造及拷贝构造函数
  • 析构函数
  • 常用接口
    • 迭代器
    • 空间接口
    • 元素查看
    • 更改元素
      • assign
      • push_back&&pop_back
      • insert
        • 迭代器失效

前言

vector是C++中stl的一个类,我们用它进行储存各种数据包括但不限于(int,double,string……)甚至可以用vector储存vector的其他容器.我们的vector是通过模板实现的如果大家对模板不熟悉建议先学习模板模板初阶<C++初阶>(跑路人笔记)_就一个挺垃圾的跑路人的博客-CSDN博客

本次我们还是使用vector - C++ Reference (cplusplus.com)cplusplus网站来讲解vector的接口以及使用.

vector介绍文档

我们的vector是通过模板来实现多类型的存储的,其中第一个模板参数T是我们传来的类型如int等,第二个是用于分配内存池空间的(可以先粗略的理解成new)

下面是对vector文档内容的翻译

  1. vector是表示可变大小数组的序列容器。

  2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。

  3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小

为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是

一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大

小。

  1. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增

长。

  1. 与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在

    末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和

    forward_lists统一的迭代器和引用更好

vector内部的重命名

上图是对vector中内容出现的重命名内容的解释.

vector的构造及拷贝构造函数

C++98所支持的构造和拷贝构造函数如上图.(因为alloc这个是后期知识所以现在可以暂时放置不管).

下面我来简单的介绍一下部分构造函数.

其中构造函数3可能会有一些费解,我在这里讲解一下:

因为第三个构造函数是模板所以只要是相同类型的两个都可以传来使用.也就如v3传来的 char*,char*.传两个迭代器也是可以的.从这里其实可以看出vector的迭代器和指针其实是非常相似的.(我们在部分版本的stl库中也可以看到直接把指针重命名成为迭代器的情况).迭代器知识模拟着指针的形式进行操作,但是绝对不能简单的把迭代器理解成指针.

其他不做过多解释

析构函数

没啥可讲的

如下图:

常用接口

因为我们学习过string的原因所以我就不再十分详细的讲解了主要介绍 作用 常见错误 等问题.

迭代器

和string的迭代器使用类似

不过使用的时候要表明类型.

使用案例:

再次强调:迭代器只是模拟了指针的行为,但是绝对不是仅仅只是指针.

空间接口

)

size和length的作用相同不过一个是老一版使用的一个是因为length不实用而重新弄得新名字(我们都可以使用不过使用size是更好的选择因为到后面树的部分就是size了).

size: 返回现存元素个数

max_size: 一个几乎无用的接口他的作用就是返回这个数组最大可容纳的元素.

resize: 扩容并扩大size和string类似不赘述

capacity: 返回容量

empty: 判断vecior是否为空

reserve: 扩容但不能缩容和string类似不赘述

shrink_to_fit: 缩小空间.(C++11支持)

capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。

这个问题经常会考察,不要固化的认为,顺序表增容都是2倍,具体增长多少是根据具体的需求定义

的。vs是PJ版本STL,g++是SGI版本STL。

元素查看

operator[]: 对[]的重载返回对应下标元素报错是assert

at: 和operator[]的功能类似但是报错是抛异常

front: 第一个元素 元素为空则报错

back: 返回最后一个元素的值 元素为空则报错

data为C++11引进的先不做介绍

更改元素

这一部分比较重要因为这里更改元素中vector有着和string不同的地方.

assign

分配一个新空间给vector元素

v1就从没有元素到将arr中的空间给了v1,准确的说是拷贝了过去因此你对arr的改变并不会使assign发生改变

当然使用其他同类型的vector的迭代器传过去也是可以的.

push_back&&pop_back

push_back 将一个元素放在尾端空间不够就自动扩容.

pop_back 删除一个尾部元素

insert

我们在插入元素的时候总会遇到因为内存不够而扩容的情况.

而当扩容时我们又是换了一个新的地址作为内存空间所以当我们使用迭代器去插入元素的时候就很有可能遇到内存换位置了但是pos没更新的情况.这种情况就是insert最需要关注的地方.我们称之为[迭代器失效](# 迭代器失效)

上图中的第一个单个元素插入的情况的返回值就是解决这个问题的关键了.

我们可以通过让pos = insert(… , …);来解决该问题.具体我放在[迭代器失效](# 迭代器失效)中讲解

下面时对insert的实例讲解.

void test4()
{
	int a[] = { 1, 2, 3, 4 };
	vector v(a, a + sizeof(a) / sizeof(int));
	// 使用find查找3所在位置的iterator
	vector::iterator pos = find(v.begin(), v.end(), 3);

	// 在pos位置之前插入30
	v.insert(pos, 30);
	vector::iterator it = v.begin();
	while (it != v.end()) 
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	pos = find(v.begin(), v.end(), 3);
	// 删除pos位置的数据
	v.erase(pos);
	it = v.begin();
	while (it != v.end()) 
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}
迭代器失效

迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了封装,比如:vector的迭代器就是原生态指针T*。因此迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器,程序可能会崩溃)。

而造成vector的迭代器失效原因有:

  1. 会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、assign、push_back等。只要空间发生改变都会导致迭代器失效.

  2. 指定位置元素的删除操作--erase

#include 
using namespace std;
#include 
int main()
{
	int a[] = { 1, 2, 3, 4 };
	vector v(a, a + sizeof(a) / sizeof(int));
	// 使用find查找3所在位置的iterator
	vector::iterator pos = find(v.begin(), v.end(), 3);
	// 删除pos位置的数据,导致pos迭代器失效。
	v.erase(pos);
	cout << *pos << endl; // 此处会导致非法访问
	return 0;
}

erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了

而我们把

v.erase(pos);换成pos = v.erase(pos);就不会失效了

加粗样式

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1019638.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号