1、概述
一个容器就是一些特定类型对象的集合。
顺序容器类型 | 描述 |
---|---|
vector | 可变大小数组,支持快速访问,在尾部之外的地方插入或删除时可能很慢 |
deque | 双端队列。支持快速访问,在头尾插入删除会很快。 |
list | 双向列表。只支持双向顺序访问。插入删除很快 |
forward_list | 单向列表。只支持单向顺序访问,在任何位置插入或删除都很快 |
array | 固定大小数组 |
string | 与vector类似,专门用于保存字符。 |
1.1、确定使用那种顺序容器
通常,使用vector是最好的选择,除非你有很好的理由选择其他容器
2、容器库
一般来说,容器都定义在同名的头文件中。容器均定义为模版类。
没有默认构造函数的类,在创建容器时,不能只传递一个元素数目参数:
vector<noDefault>v1(10,init);//正确,提供了元素初始化器
vector<noDefault>v2(10);//错误
容器操作 | 描述 |
---|---|
iteratro | 迭代器 |
const_iterator | 可以读取元素,但是不能修改元素的迭代器类型 |
size_type | … |
… | … |
2.1、迭代器
迭代器范围
左闭合区间[begin end)
list<string>::iterator iter; //迭代器类型
2.2、容器定义和初始化
将一个容器初始化为另一个容器的拷贝,有两种方法:
- 可以直接拷贝整个容器,
- 或者(array除外)拷贝由一个迭代器指定的范围。
list<string> authors = {"Tom","Jack","Rose"};
vector<const char*> articles = {"a","an","the"};
list<string> author1(authors);
deque<string> author2(authors);//错误,容器类型不匹配
vector<string> author3(authors);//错误,容器类型不匹配
forward_lsit<string> words(articles.begin(),articles.end());
列表初始化
list<string> authors = {"a","b","c"};
标准库array具有固定大小
array<int, 10>;
array<string, 10>;
array可以进行拷贝
array<int,7> arr1 = {0,1,2,3,4,5,6};
array<int,7> arr2 = arr1; //正确,只要数组类型匹配即合法(大小需一样)
使用assign
仅顺序容器(array除外)。
用参数所指定的元素(的拷贝)替换左边容器中的所有元素。
list<string> names;
vector<const char*> oldstyle;
names = oldstyle; //错误,容器类型不匹配
names.assign(oldstyle.cbegin().oldstyle.cend());
//assign另一个版本
list<string>slist1(1);
slist1.assign(10,"hehe");//10个元素,都是“hehe”
使用swap
交换相同类型容器的内容
vector<string> svec1(10);
vector<string> svec1(15);
swap(svec1,svec2);//交换后,svec1为包含15个元素,svec2包含10个元素
容器大小操作
empty,size,max_size
关系运算符
类似于string
如果元素类型不支持运算符操作,则不能进行相应的关系运算。
3、顺序容器操作
3.1、添加元素
forward_list,专有的insert和emplace,不支持push_back和 emplace_back
vector,string不支持push_back和 emplace_back
使用push_back
使用push_front
使用emplace操作
新标准引入emplace, emplace_back, empalce_front
调用emplace时,将参数传递给元素类型的构造函数,直接构造元素。
class A{
public:
A(string name, int age);
private:
string name;
int age;
}
c.emplace_back("Jack",23);//将参数传给A的构造函数,构造元素
c.push_back("Jack",23);//错误
c.push_back(A("Jack",23));//正确
3.2、访问元素
c.front();
c.back();
c.at(n);
c[n];
3.3、删除元素
pop_front, pop_back, erase
3.4、特殊的forward_list操作
insert_after, emplace_after,erase_after
before_begin返回一个首前(off-the-beginning)迭代器。这个迭代器允许我们在链表受元素之前不存在的元素之后添加或删除元素。
3.5、改变容器大小
alist.resize(10);
alist.resize(25,-1);
3.6、容器操作可能会使迭代器失效
4、vector对象增长
4.1、管理容量的成员函数
c.shrink_to_fit();//将capacity减小为和size相同大小
c.capacity(); //容器可容纳的元素个数
c.reserve(n);//分配至少能容纳n个元素的内存空间
4.2、capacity和size
size:已经保存的元素的数量
capacity:最多可保存的元素数量
5、改变string的其他方法
assign
insert
erase
append
replace
find
rfind
find_first_of
find_last_of
find_first_ont_of
find_last_not_of
compare
to_string
stoi
stol
stoul
stoll
stoull
stof
stod
stold
6、容器适配器
6.1、三种适配器
stack
queue
priority_queue.
容器、迭代器和函数都有适配器。
本质上,适配器是一种机制,能使某种事物的行为看起来像另一种事物一样。
6.2、定义一个适配器
适配器提供两个构造函数:
- 默认构造函数创建一个空对象
- 接受一个容器的构造函数,拷贝该容器来初始化适配器。
stack<int> stk(deq);//deq是一个deque<int>容器