107 C++ STL 容器分类,array,vector详解

STL 的组成部分是个重要的部分,先回忆一下

容器,迭代器,算法(函数),分配器(分配内存),适配器,仿函数

一 容器的分类.

vector , list,map

容器是保存数据,用于管理一大堆数据。

分为三大类

第一类:顺序容器,sqquence containers.放进去在哪里,这个元素就排在哪里,例如,array, vector,deque,list,forward_list

第二类:关联容器 associative containers ,一般都是键值对.特别适合做查找。

关联容器你只能控制插入的数据,不能控制插入的位置。

set, map, multiset,multimap,hash_set,hash_map

第三类: 无序容器 unordered containers C++11推出来的。

元素的位置不重要,重要的是这个元素是否在这个集合里面。

无序容器实际上也属于一种关联容器。

无序容器里面的元素可能随着 新的元素的增加让原来元素的位置发生变化,这是无序容器内部 的算法决定的。

unordered  set/ multiset

unordered  map/ multimap

107 C++ STL 容器分类,array,vector详解_第1张图片

二 容器的说明和应用事项例

array: 是一个顺序容器,其实是一个数组,大小是固定的,刚开始申请的大小是多少,就是多少,不能扩展。

#include

std::array C++文档说明

< cpp‎ | container

在标头 定义

template<

    class T,
    std::size_t N

> struct array;
(C++11 起)

std::array 是封装固定大小数组的容器。

此容器是一个聚合类型,其语义等同于保有一个 C 风格数组 T[N] 作为其唯一非静态数据成员的结构体。不同于 C 风格数组,它不会自动退化成 T* 。它能作为聚合类型聚合初始化,只要有至多 N 个能转换成 T 的初始化器: std::array a = {1,2,3}; 。

该结构体结合了 C 风格数组的性能、可访问性与容器的优点,比如可获取大小、支持赋值、随机访问迭代器等。

std::array 满足容器 (Container) 和可逆容器 (ReversibleContainer) 的要求,除了默认构造的 array 是非空的,以及进行交换的复杂度是线性,它满足连续容器 (ContiguousContainer) (C++17 起)的要求并部分满足序列容器 (SequenceContainer) 的要求。

当其长度为零时 arrayN == 0 )有特殊情况。此时, array.begin() == array.end() ,并拥有某个唯一值。在零长 array 上调用 front() 或 back() 是未定义的。

亦可将 array 当做拥有 N 个同类型元素的元组。

迭代器非法化

按照规则,指向 array 的迭代器在 array 的生存期间决不非法化。然而要注意,在 swap 时,迭代器将继续指向同一 array 的元素,并将改变元素的值。

107 C++ STL 容器分类,array,vector详解_第2张图片

测试验证:

#include 


//STL array
void main() {
	array arr = {"nihao","ilovelovelovelovelovelovelovelove","wang"};
	cout << arr.size() << endl;//5
	cout << arr.max_size()<

5
5
012FFAFC
nihao
 p = 012FFB00
012FFB18
ilovelovelovelovelovelovelovelove
 p = 017677E0
012FFB34
wang
 p = 012FFB38
012FFB50

 p = 012FFB54
012FFB6C

 p = 012FFB70

107 C++ STL 容器分类,array,vector详解_第3张图片

这里涉及到string 在布局问题,可以查看

102 C++ string内存模型分析-CSDN博客

vector 详解

从下图我们就能知道,

1.vector 是顺序存储的,从vector的末尾加资源或者删除资源都很快。 push_back();

2.往中间插入元素可能导致很多后续元素都要执行重新构造,析构,效率会非常的低

3.查找速度不会快.

4.vector容器内存也是挨着的。

5.vector 是可变大小的容器。

6.从4和5可以推断出:当存储多个Teacher的时候,会有问题发生。

当第一次存储一个Teacher的时候,vector只会开出一个容纳 一个 Teacher size的空间。

当第二次存储另一个Teacher的时候,vector为了保证内存连续,则会重新开辟一个可以容纳2个Teacher的空间大小,然后将Teacher1 copy构造过来。然后加上一个Teacher2.

当第三次存储第三个Teacher的时候,vector为了保证内存连续,则会重新开辟一个可以容纳3个Teacher的空间大小,然后将Teacher1 和 Teacher2 copy构造过来。然后加上一个Teacher3

7.怎么改良这个呢?

vector虽然好用,但是从上述能看出来,这玩意是因为每次都搞一个空间,导致Teacher 类的,构造函数,copy 构造函数,析构函数,会被频繁的调用,这很影响效率。实际上,由于代码是我们自己写的,在某些情况下,我们很容易知道,大概这个vector会容纳多少个Teacher,因此可以在开始的时候,通过 vector.

107 C++ STL 容器分类,array,vector详解_第4张图片

问题发生时的代码

void main() {
	vector vec;

	for (int i = 0; i < 5; ++i) {
		cout << "start i = " << i << endl;
		vec.push_back(Teacher6(i));

		//start i = 0
		//	Teacher6 gouzao mage = 0 this = 0093F6D8  //先构造 Teacher6(0)
		//	Teacher6 copy gouzao  this = 00E02680  obj = 0093F6D8//然后将Teacher6(i)通过copy 构造 copy 给 vector中
		//	Teacher6 xigou  this = 0093F6D8 //然后将Teacher6(0) 析构
		//	start i = 1
		//	Teacher6 gouzao mage = 1 this = 0093F6D8//先构造 Teacher6(1)
		//	Teacher6 copy gouzao  this = 00E00D84  obj = 0093F6D8//然后将Teacher6(i)通过copy 构造 copy 给 vecto
		//	Teacher6 copy gouzao  this = 00E00D80  obj = 00E02680 //将vector 中的第一个元素通过 copy 构造到新的位置上
		//	Teacher6 xigou  this = 00E02680 //将之前的vector中的元素析构
		//	Teacher6 xigou  this = 0093F6D8 //把 Teacher6(1)析构了
		//	start i = 2
		//	Teacher6 gouzao mage = 2 this = 0093F6D8
		//	Teacher6 copy gouzao  this = 00E00B20  obj = 0093F6D8
		//	Teacher6 copy gouzao  this = 00E00B18  obj = 00E00D80
		//	Teacher6 copy gouzao  this = 00E00B1C  obj = 00E00D84
		//	Teacher6 xigou  this = 00E00D80
		//	Teacher6 xigou  this = 00E00D84
		//	Teacher6 xigou  this = 0093F6D8
		//	start i = 3
		//	Teacher6 gouzao mage = 3 this = 0093F6D8
		//	Teacher6 copy gouzao  this = 00DF6E24  obj = 0093F6D8
		//	Teacher6 copy gouzao  this = 00DF6E18  obj = 00E00B18
		//	Teacher6 copy gouzao  this = 00DF6E1C  obj = 00E00B1C
		//	Teacher6 copy gouzao  this = 00DF6E20  obj = 00E00B20
		//	Teacher6 xigou  this = 00E00B18
		//	Teacher6 xigou  this = 00E00B1C
		//	Teacher6 xigou  this = 00E00B20
		//	Teacher6 xigou  this = 0093F6D8
		//	start i = 4
		//	Teacher6 gouzao mage = 4 this = 0093F6D8
		//	Teacher6 copy gouzao  this = 00E02B40  obj = 0093F6D8
		//	Teacher6 copy gouzao  this = 00E02B30  obj = 00DF6E18
		//	Teacher6 copy gouzao  this = 00E02B34  obj = 00DF6E1C
		//	Teacher6 copy gouzao  this = 00E02B38  obj = 00DF6E20
		//	Teacher6 copy gouzao  this = 00E02B3C  obj = 00DF6E24
		//	Teacher6 xigou  this = 00DF6E18
		//	Teacher6 xigou  this = 00DF6E1C
		//	Teacher6 xigou  this = 00DF6E20
		//	Teacher6 xigou  this = 00DF6E24
		//	Teacher6 xigou  this = 0093F6D8
		//	Teacher6 xigou  this = 00E02B30
		//	Teacher6 xigou  this = 00E02B34
		//	Teacher6 xigou  this = 00E02B38
		//	Teacher6 xigou  this = 00E02B3C
		//	Teacher6 xigou  this = 00E02B40
	}
}

改动后的代码:

void main() {
	vector vec;
	cout << vec.capacity() << endl;
	cout << vec.size() << endl;
	vec.reserve(10);
	cout << vec.capacity() << endl;
	cout << vec.size() << endl;
	for (int i = 0; i < 5; ++i) {
		cout << "start i = " << i << endl;
		vec.push_back(Teacher6(i));
	}
	//  0
	//	0
	//	10
	//  0
	//  start i = 0
	//	Teacher6 gouzao mage = 0 this = 00D9F8D0
	//	Teacher6 copy gouzao  this = 014B6E18  obj = 00D9F8D0
	//	Teacher6 xigou  this = 00D9F8D0
	//	start i = 1
	//	Teacher6 gouzao mage = 1 this = 00D9F8D0
	//	Teacher6 copy gouzao  this = 014B6E1C  obj = 00D9F8D0
	//	Teacher6 xigou  this = 00D9F8D0
	//	start i = 2
	//	Teacher6 gouzao mage = 2 this = 00D9F8D0
	//	Teacher6 copy gouzao  this = 014B6E20  obj = 00D9F8D0
	//	Teacher6 xigou  this = 00D9F8D0
	//	start i = 3
	//	Teacher6 gouzao mage = 3 this = 00D9F8D0
	//	Teacher6 copy gouzao  this = 014B6E24  obj = 00D9F8D0
	//	Teacher6 xigou  this = 00D9F8D0
	//	start i = 4
	//	Teacher6 gouzao mage = 4 this = 00D9F8D0
	//	Teacher6 copy gouzao  this = 014B6E28  obj = 00D9F8D0
	//	Teacher6 xigou  this = 00D9F8D0
	//	Teacher6 xigou  this = 014B6E18
	//	Teacher6 xigou  this = 014B6E1C
	//	Teacher6 xigou  this = 014B6E20
	//	Teacher6 xigou  this = 014B6E24
	//	Teacher6 xigou  this = 014B6E28
}

特别注意的是:vector 的不恰当使用,会造成效率很低,使用时要非常小心

你可能感兴趣的:(c++,开发语言)