文章目录
- 简介
- vector中的成员类型
- 模板参数
- 头文件的包含
- 构造函数
- vector的访问方式:
- 下标[ ]
- 迭代器
- 范围for
- 交换swap
简介
vector是stl中的一种数组容器,vector在英文中有矢量的意思,但实际上在数据结构中就是一种类似于数组的结构;
与之前学习的string不同,string是针对字符串的一个容器,而vector却是一个类模板,意思就是vector这个容器中,可以存放的数据不只只有内置类型,同时也有自定义类型;
内置类型 | 自定义类型 |
vector< int > | vector< string > |
vector< double > | vector< vector< int > > |
vector< char > | ...... |
...... | ...... |
vector中的成员类型
作为一个类模板,vector中有许多的成员类型,这些成员类型一般是在类域中typedef出来的类型;
[图片源自cplusplus]
模板参数
该类模板中共有两个模板参数;
- class T
该模板参数为数据类型,即vector中保存的数据类型; - class Alloc = allocator< T >
该模板参数为内存池的类型,不过该模板参数给了一个缺省值,默认所给的这个缺省值为标准库中的内存池,同时也可以自己实现一个内存池进行传参;
头文件的包含
在使用vector时需要包含头文件;
#include <vector>
构造函数
在C++98的版本中,vector共有四个构造函数;
explicit vector (const allocator_type& alloc = allocator_type()) | 构造一个空的vector |
explicit vector (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type()); | 用n个val进行构造 |
template vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); | 迭代器构造 |
vector (const vector& x) | 拷贝构造 |
#include<iostream>#include<vector>using namespace std;namespace std {void test_vector_Creat() {/** 构造一个空的vector<int> 对象*/vector<int> a;a.push_back(1);a.push_back(2);a.push_back(3);a.push_back(4);/** 用10个6构造一个vector<int> 对象*/vector<int> b(10, 6);/** 用b的迭代器范围构造一个vector<int> 对象*/vector<int> c(b.begin() + 6, b.end());/** 以c作为参数拷贝构造一个vector<int> 对象*/vector<int> Copy_c(c);cout << "a:";for (auto in : a) {cout << in << " ";}cout << endl;cout << "b:";for (auto in : b) {cout << in << " ";}cout << endl;cout << "c:";for (auto in : c) {cout << in << " ";}cout << endl;cout << "Copy_c:";for (auto in : Copy_c) {cout << in << " ";}cout << endl;}}
vector的访问方式:
下标[ ]
在vector中,可以实现像数组或者string那样以下标和下标访问操作符[ ]进行数据的访问;
最主要的原因是在vector中存在与string容器一样的[ ]操作符重载;
同样的,在vector中也拥有两个版本的重载,返回值中的reference即为引用的意思,返回值返回一个引用;
同时另一个版本的const_reference返回值为返回一个const修饰的引用;
在使用时会自动根据需要进行返回;
迭代器
迭代器的使用方法与string中的迭代器使用方法相同,唯一的不同点是,在vector中使用迭代器不能使用类名,而是应该使用类型名;
vecror <int> ::iterator it = xxx.begin();
该迭代器也为前闭后开区间;
范围for
范围for的底层实际上就是替换成了迭代器,对于存储内置类型的vector来说,并不会有什么影响,而若是使用存储自定义类型的vector的范围for则需要注意;
vector<string> strV;
strV.push_back("张三");
strV.push_back("李四");
strV.push_back("王五");for(auto str:strV){cout<<str<<endl;
}
在上面这段代码中出现了一个问题,由于范围for的底层为使用迭代器遍历整个vector,但是范围for只是将一个对象赋值到一个变量;
在这里将每个string对象赋值给str,由于这里是临时对象,将会出现深浅拷贝的问题,若是将vector中的每个string对象都赋值到str中,将会进行隐式类型转换并进行深拷贝,加大开销;
若是想用范围for来遍历存储自定义类型的vector,则最好的办法是利用引用,若是害怕数据在遍历过程中被更改,即可以加上const修饰;
vector<string> strV;
strV.push_back("张三");
strV.push_back("李四");
strV.push_back("王五");for(const auto& str:strV){cout<<str<<endl;
}
交换swap
在vector中也有一个swap成员函数,该函数也是为了避免容器自定义类型使用标准库中的swap函数导致产生过大开销;
vector::swap( ) 的使用也与string::swap( ) 相同,本质上就是交换指针或者数据;
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);vector<int> v2;
v1.push_back(5);
v1.push_back(5);
v1.push_back(3);
v1.push_back(3);v1.swap(v2);