【C++】STL中vector容器的详细功能

前言

在上期的简单使用之后,我们并未介绍完vector中提供的所有的方法,下面即将揭开vector的神秘面纱。

(一) vector基本概念

vector是一种数据结构,与数组类似,也称单端数组,熟知的push_back()、pop_back()都是在元素的尾部进行插入和删除;

数组和vector的区别:

  • vector相对于数组可以动态扩容
  • vector相对于数组有一系列的函数操作

vector的逻辑图:
在这里插入图片描述
注:

  • vc.front()和vc.back()是int类型,指的是vector容器中首尾元素本身
  • vc.begin()、vc.end()、vc.rbegin()、vc.rend()都是vector*的地址,对应的就是元素的地址,可以给迭代器赋值;

(二)vector函数的使用

(1)vector的构造函数

  • vector<T> 变量名; 无参构造
  • vector(const vector& vc) 拷贝构造
  • vector(vc.begin(), vc.end()); 将[vc.begin(),vc.end())的所有元素拷贝给新构造的容器
  • vector(n, elem); n代表个数,elem是初始化的值

(2)vector的赋值操作

  • vector& operator=(const vector &src);赋值运算符的重载
  • assign(beg, end); [beg, end)的元素拷贝给新容器
  • assign(n, elem); n个elem的赋值

(3)vector的容量和大小

  • empty(); 判断容器是否为空
  • capacity(); 返回容器的容量
  • size(); 返回容器中的元素个数
  • resize(int num); 重新改变容器的元素个数,个数变多num>size(),使用默认值0填充新位置;若变短num<size() ,超出长度的元素被删除,但是容量不会变
  • resize(int num, elem);同上,只不过超出num>size()的情况使用elem进行填充

(4)vector的插入删除操作

  • push_back(elem);尾插
  • pop_back();尾删
  • insert(const_iterator pos, elem);迭代器指向的pos位置,插入元素elem
  • insert(const_iterator pos, int count, elem);迭代器指向的pos位置插入count 个elem
  • erase(const_iterator pos);删除迭代器指向位置的元素
  • erase(const_iterator start, const_iterator end);删除迭代器指向start~end位置的元素
  • clear()清空容器

(5)vector的数据存取

  • at(int index) 返回索引 index所值的数据
  • operator[] 返回索引 index 所指的数据
  • front() 返回容器中第一个数据元素
  • back() 返回容器中最后一个数据元素

(6)vector的互换容器

vc2.swap(vc1);

  • 功能:
    实现两个vector容器之间数据的交换(不仅是容器中的每一个元素,还包括容器的长度、容量)

  • 实际功能:收缩内存空间
    假设vc.capacity()容器的容量非常大,但只存储了很少的元素,那如果一直使用vc的话是不是很吃内存空间呢

所以,我们的思路就是定义一个新容器,拥有较小的容量,并且能够存储vc的中的元素,然后丢弃原来的vc容器就好了。

  • 这里我们使用了匿名对象:
vector<int> (vc).swap(vc);

这句代码的意思就是使用vc拷贝构造一个匿名对象来与vc容器进行元素数据交换。匿名对象容器保存着vc原有的大容量,但是这句执行完毕后匿名对象就会被析构,被系统释放。而对于vc来说,保存着匿名对象的长度和容量;

注:
swap先交换容器中的每一个元素,再交换容器的长度,容量大小;由于容器的元素的增加都可能导致动态扩容,只有元素交换完成,才能确定当前容器的长度和容量大小

(7)vector预留空间

  • 功能:
    减少vector在动态扩容的次数

  • reserve函数:容器预留len个元素长度,(预留空间已开辟但未初始化,不可访问)
    reserve(int len);

  • 使用情景
    在出入数据之前已知数据量的个数,可以使用预留空间,减少扩容次数,提高效率。

  • 代码示例:

#include <iostream>
#include <vector>

using namespace std;
int main()
{
    
    
	vector<int> vc;
	int *p = NULL;
	int count = 0;	//扩容次数
	for(int i = 0; i < 2000; i++)
	{
    
    
		vc.push_back(i);
		if(p != &vc[0])
		{
    
    
			p = &vc[0];
			count++;
		}
	}
	cout << count <<endl;
	return 0; 
}

结果:可见2000个数据的插入扩容了20次
在这里插入图片描述

  • 使用vc.reserve()来优化吧
#include <iostream>
#include <vector>

using namespace std;
int main()
{
    
    
	vector<int> vc;
	vc.reserve(2000);
	int* p = NULL;
	int count = 0;	//扩容次数
	for (int i = 0; i < 2000; i++)
	{
    
    
		vc.push_back(i);
		if (p != &vc[0])
		{
    
    
			p = &vc[0];
			count++;
		}
	}
	cout << count << endl;
	return 0;
}

优化结果:
在这里插入图片描述

(三)下期内容


C++下一期:STL中vector容器的仿写

Guess you like

Origin blog.csdn.net/xiaoxiaoguailou/article/details/121380697