F_JustWei's Studio.

C++容器 vector

字数统计: 2.7k阅读时长: 12 min
2021/05/15 Share

C++容器 vector

vector 是一种可以改变大小的序列容器。

和 array 一样,vector 的元素也是连续存储的,这意味着不仅可以通过迭代器访问元素,还可以使用指向元素的常规指针的偏移量来访问元素,并且效率与 array 相同。但是与 array 不同的是,vector 的大小可以动态改变,其存储由容器自动处理。

vector 在内部使用动态分配的数组存储其元素。插入新元素时,可能需要重新分配该数组以增大其大小,这意味着分配新数组并将所有元素移至该数组。就处理时间而言,这是一项相对昂贵的任务。

所以,vector 可能会分配一些额外的存储空间以适应可能的增长,因此,该容器的实际容量可能会大于包含其元素的个数(即其大小)所严格要求的存储容量。vector 可以实现不同的增长策略,以便在内存使用和重新分配之间取得平衡,但是在任何情况下,重新分配仅应以大小的对数增长间隔进行,以便可以在 vector 末尾插入单个元素提供线性的时间复杂性。

因此,与 array 相比,vector 消耗更多内存以换取管理存储和有效的动态增长能力

与其它动态序列容器(deque,list 和 forward_list)相比,vector 非常有效地访问其元素(就像 array 一样),并且相对高效地从其末尾添加或删除元素。对于涉及在末尾以外的位置插入或删除元素的操作,它们的性能比其它动态序列容器差,并且与 list 和 forward_list 相比,迭代器和引用的一致性更差。

模板参数(Template parameters)

1
template <class _Ty, class _Alloc = allocator<_Ty>>//_Ty是元素的类型,_Alloc是分配器类型,有默认的分配器

成员函数(Member functions)

1
2
3
4
5
6
7
8
9
10
11
12
13
using value_type      = _Ty;
using allocator_type = _Alloc;
using pointer = typename _Alty_traits::pointer;
using const_pointer = typename _Alty_traits::const_pointer;
using reference = _Ty&;
using const_reference = const _Ty&;
using size_type = typename _Alty_traits::size_type;
using difference_type = typename _Alty_traits::difference_type;

using iterator = _Vector_iterator<_Scary_val>;
using const_iterator = _Vector_const_iterator<_Scary_val>;
using reverse_iterator = _STD reverse_iterator<iterator>;
using const_reverse_iterator = _STD reverse_iterator<const_iterator>;

成员函数(Member functions)

函数名 函数功能
begin 返回第一个元素的 iterator
end 返回最后一个元素的下一个元素的 iterator
rbegin 返回反向迭代器反向开始的 iterator
rend 返回反向迭代器返回到反向端点的 iterator
cbegin 返回第一个元素的 const_iterator
cend 返回最后一个元素的下一个元素的 const_iterator
crbegin 返回反向迭代器反向开始的 const_iterator
crend 返回反向迭代器返回到反向端点的 const_iterator
size 返回大小
max_size 返回最大大小
resize 重新申请并改变当前 vector 对象的有效空间(size)大小
capacity 返回分配的存储容量的大小
empty 测试数组是否为空
reserve 重新申请并改变当前 vector 对象的总空间(capacity)大小
shrink_to_fit 降低其容量和 size 匹配
operator[] 访问元素
at 访问元素
front 访问第一个元素
back 访问最后一个元素
data 获取指向数据的指针
assign 拷贝
push_back 在末尾添加元素
pop_back 删除最后一个元素
insert 插入元素
erase 删除元素
swap 交换内容
clear 清除内容
emplace 构造和插入元素
emplace_back 在最后构造并插入元素
get_allocator 获取分配器
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <vector>
#include <iostream>
using namespace std;
const int SIZE = 10;
int main() {
//默认初始化,vector为空, size为0,表明容器中没有元素,而且 capacity 也返回 0,意味着还没有分配内存空间。
//这种初始化方式适用于元素个数未知,需要在程序中动态添加的情况。
vector<int> a;

//两种方式等价,b 初始化为 a 的拷贝,b 必须与 a 类型相同。
//也就是同为int的vector类型,a 将具有和 b 相同的容量和元素。
vector<int> b(a);// vector<int> b = a;

//c 初始化为列表中元素的拷贝,列表中元素必须与 c 的元素类型相容。
//必须是与整数类型相容的类型,整形会直接拷贝,其他相容的类型会进行类型转换。
vector<int> c{ 0,1,2,3,4,5,6,7,8,9 };//vector<int> c = { 0,1,2,3,4,5,6,7,8,9 };

//d 初始化为两个迭代器指定范围中元素的拷贝(前闭后开),范围中的元素类型必须与 d 的元素类型相容
vector<int> d(c.begin(), c.end());

//默认值初始化,e 中将包含 10 个元素,每个元素进行缺省的值初始化,对于int,也就是被赋值为0。
//e 被初始化为包含 10 个 0。当程序运行初期元素大致数量可预知,而元素的值需要动态获取的时候,可采用这种初始化方式。
vector<int> e(10);

//指定值初始化,f 被初始化为包含 10 个值为 1 的int
vector<int> f(10, 1);
//赋值
vector<int> v(SIZE);
for (int i = 0; i < v.size(); i++) {
v[i] = rand();
}
//输出
for (int i = 0; i < v.size(); i++) {
cout << "v 的第 " << i << " 个元素:" << v[i] << " " << endl;
}
cout << endl;
//8种迭代器
auto begin = v.begin(); //返回第一个元素的iterator
auto end = v.end(); //返回最后一个元素的下一个元素的iterator
auto rbegin = v.rbegin(); //返回最后一个元素的iterator
auto rend = v.rend(); //返回第一个元素的前一个元素的iterator
auto cbegin = v.cbegin(); //返回const_iterator,该const_iterator指向第一个元素
auto cend = v.cend(); //返回const_iterator,该iconst_iterator指向最后一个元素的下一个元素
auto crbegin = v.crbegin(); //返回const_iterator,该const_iterator指向最后一个元素
auto crend = v.crend(); //返回const_iterator,该const_iterator指向第一个元素的前一个元素
//函数
cout << "vector.size() = " << v.size() << endl;
cout << "vector.max_size() = " << v.max_size() << endl;
cout << "vector.capacity() = " << v.capacity() << endl;
cout << "vector.empty() = " << v.empty() << endl;
cout << "vector.at(0) = " << v.at(0) << endl;
cout << "vector.front() = " << v.front() << endl;
cout << "vector.back() = " << v.back() << endl;
cout << "vector.data() = " << v.data() << endl;

cout << endl << "change size and capacity" << endl;
v.resize(5);
v.reserve(100);
cout << "vector.size() = " << v.size() << endl;
cout << "vector.capacity() = " << v.capacity() << endl;

cout << endl << "降低其容量和 size 匹配" << endl;
v.shrink_to_fit();
cout << "vector.size() = " << v.size() << endl;
cout << "vector.capacity() = " << v.capacity() << endl;

vector<int> t;
cout << endl << "assign的第一种用法" << endl;
t.assign(v.begin(), v.end());
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}

cout << endl << "assign的第二种用法" << endl;
t.clear();
t.assign(SIZE, 1);
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}

cout << endl << "push_back(100)" << endl;
t.push_back(100);
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}

cout << endl << "pop_back()" << endl;
t.pop_back();
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}

cout << endl << "insert(t.begin(), 100)" << endl;
t.insert(t.begin(), 100);
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}

cout << endl << "erase(t.begin())" << endl;
t.erase(t.begin());
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}

t.swap(v);
cout << endl << "t.swap(v)" << endl;
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}

return 0;
}
输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
v 的第 0 个元素:41
v 的第 1 个元素:18467
v 的第 2 个元素:6334
v 的第 3 个元素:26500
v 的第 4 个元素:19169
v 的第 5 个元素:15724
v 的第 6 个元素:11478
v 的第 7 个元素:29358
v 的第 8 个元素:26962
v 的第 9 个元素:24464

vector.size() = 10
vector.max_size() = 1073741823
vector.capacity() = 10
vector.empty() = 0
vector.at(0) = 41
vector.front() = 41
vector.back() = 24464
vector.data() = 00FF3580

change size and capacity
vector.size() = 5
vector.capacity() = 100

降低其容量和 size 匹配
vector.size() = 5
vector.capacity() = 5

assign的第一种用法
t 的第 0 个元素:41
t 的第 1 个元素:18467
t 的第 2 个元素:6334
t 的第 3 个元素:26500
t 的第 4 个元素:19169

assign的第二种用法
t 的第 0 个元素:1
t 的第 1 个元素:1
t 的第 2 个元素:1
t 的第 3 个元素:1
t 的第 4 个元素:1
t 的第 5 个元素:1
t 的第 6 个元素:1
t 的第 7 个元素:1
t 的第 8 个元素:1
t 的第 9 个元素:1

push_back(100)
t 的第 0 个元素:1
t 的第 1 个元素:1
t 的第 2 个元素:1
t 的第 3 个元素:1
t 的第 4 个元素:1
t 的第 5 个元素:1
t 的第 6 个元素:1
t 的第 7 个元素:1
t 的第 8 个元素:1
t 的第 9 个元素:1
t 的第 10 个元素:100

pop_back()
t 的第 0 个元素:1
t 的第 1 个元素:1
t 的第 2 个元素:1
t 的第 3 个元素:1
t 的第 4 个元素:1
t 的第 5 个元素:1
t 的第 6 个元素:1
t 的第 7 个元素:1
t 的第 8 个元素:1
t 的第 9 个元素:1

insert(t.begin(), 100)
t 的第 0 个元素:100
t 的第 1 个元素:1
t 的第 2 个元素:1
t 的第 3 个元素:1
t 的第 4 个元素:1
t 的第 5 个元素:1
t 的第 6 个元素:1
t 的第 7 个元素:1
t 的第 8 个元素:1
t 的第 9 个元素:1
t 的第 10 个元素:1

erase(t.begin())
t 的第 0 个元素:1
t 的第 1 个元素:1
t 的第 2 个元素:1
t 的第 3 个元素:1
t 的第 4 个元素:1
t 的第 5 个元素:1
t 的第 6 个元素:1
t 的第 7 个元素:1
t 的第 8 个元素:1
t 的第 9 个元素:1

t.swap(v)
t 的第 0 个元素:41
t 的第 1 个元素:18467
t 的第 2 个元素:6334
t 的第 3 个元素:26500
t 的第 4 个元素:19169
CATALOG
  1. 1. C++容器 vector
    1. 1.0.1. 模板参数(Template parameters)
    2. 1.0.2. 成员函数(Member functions)
    3. 1.0.3. 成员函数(Member functions)
      1. 1.0.3.0.1. 示例:
      2. 1.0.3.0.2. 输出: