C++容器vector
·
C++容器vector
定义
是一个动态数组,能够自动管理内存,在运行时根据需要动态增长或缩小
| 特性 | 说明 |
|---|---|
| 类型 | 序列容器(Sequence Container) |
| 底层实现 | 动态数组(连续内存) |
| 内存布局 | 元素在内存中是连续存储的 |
| 访问方式 | 支持随机访问(通过下标或迭代器) |
| 扩展性 | 自动扩容,当空间不足时重新分配更大的内存并复制元素 |
| 性能 | 尾部插入/删除:O(1) 平均;中间/头部插入/删除:O(n);随机访问:O(1) |
构造函数
1、默认构造函数
创建空vector,不含任何元素
std::string getStringFromU8string(const std::u8string& u8str) {
return std::string(reinterpret_cast<const char*>(u8str.data()), u8str.size());
}
std::u8string getU8stingFromString(const std::string& str) {
return std::u8string(reinterpret_cast<const char8_t*>(str.data()), str.size());
}
int main()
{
system("chcp 65001");
vector<std::u8string> vec;
vec.push_back(u8"北京");
vec.push_back(u8"上海");
vec.push_back(u8"广州");
vec.push_back(u8"深圳");
for (auto it : vec)
{
cout << getStringFromU8string(it) << endl;
}
}
2、指定元素个数构造函数
指定元素个数和初始值(不指定初始值就是数据类型默认值)
int main()
{
system("chcp 65001");
// 指定元素个数,没有指定默认值,就是u8string默认值
vector<std::u8string> vec(3);
// 从4个元素开始赋值,超过指定数量会自动扩容
vec.push_back(u8"北京");
vec.push_back(u8"上海");
vec.push_back(u8"广州");
vec.push_back(u8"深圳");
for (auto it : vec)
{
cout << getStringFromU8string(it) << endl;
}
// 指定元素个数,指定默认值
vector<std::u8string> vec1(3, u8"哈哈");
for (auto it : vec1)
{
cout << getStringFromU8string(it) << endl;
}
}
3、拷贝构造函数
用另一个vector来初始化新的vector
int main()
{
system("chcp 65001");
vector<std::u8string> vec1;
vec1.push_back(u8"北京");
vec1.push_back(u8"上海");
vec1.push_back(u8"广州");
vec1.push_back(u8"深圳");
// 拷贝构造函数
vector<std::u8string> vec2(vec1);
for (auto it : vec2)
{
cout << "v2:" << getStringFromU8string(it) << endl;
}
// 走的赋值,原vec1的值还在
for (auto it : vec1)
{
cout << "v1:" << getStringFromU8string(it) << endl;
}
}
4、范围构造函数
使用另外一个迭代器指定的范围来初始化新的vector
int main()
{
system("chcp 65001");
vector<std::u8string> vec1;
vec1.push_back(u8"北京");
vec1.push_back(u8"上海");
vec1.push_back(u8"广州");
vec1.push_back(u8"深圳");
// 复制全部数据
vector<std::u8string> vec2(vec1.begin(), vec1.end());
for (auto it : vec2)
{
cout << "v2:" << getStringFromU8string(it) << endl;
}
// 复制部分数据
vector<std::u8string> vec3(vec1.begin() + 1, vec1.end() - 1);
for (auto it : vec3)
{
cout << "v3:" << getStringFromU8string(it) << endl;
}
// 走的赋值,原vec1的值还在
for (auto it : vec1)
{
cout << "v1:" << getStringFromU8string(it) << endl;
}
}
5、指定初始化列表构造函数
使用花括号内的值直接初始化vector元素
int main()
{
system("chcp 65001");
vector<std::u8string> vec1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
for (auto it : vec1)
{
cout << "v1:" << getStringFromU8string(it) << endl;
}
vector<std::u8string> vec2{ u8"张三", u8"李四", u8"王五" };
for (auto it : vec2)
{
cout << "v2:" << getStringFromU8string(it) << endl;
}
}
6、基于数组的构造函数
基于数组
int main()
{
system("chcp 65001");
std::u8string array[4] = { u8"北京", u8"上海", u8"广州", u8"深圳" };
// 实际长度
int realLen = sizeof(array) / sizeof(array[0]);
vector<std::u8string> vec1(array, array + realLen);
for (auto it : vec1)
{
cout << "v1:" << getStringFromU8string(it) << endl;
}
// 走的复制,数组还在
for (auto it : array)
{
cout << "array:" << getStringFromU8string(it) << endl;
}
}
常用函数
| 函数 | 说明 |
|---|---|
size() |
返回当前元素个数 |
empty() |
判断是否为空(返回 bool) |
capacity() |
返回当前分配的存储容量(不等于 size) |
max_size() |
返回 vector 可容纳的最大元素数 |
resize(n) |
改变 size,若 n > size(),新增元素用默认值填充;n<size(),系统会采用size()的值 |
resize(n, val) |
同上,新增元素用 val 填充 |
reserve(n) |
预留至少 n 个元素的存储空间,避免频繁扩容 |
shrink_to_fit() |
请求缩小 capacity 到 size(C++11) |
int main()
{
system("chcp 65001");
vector<std::u8string> vec1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
cout << "vec1.size() = " << vec1.size() << endl;
cout << "vec1.max_size() = " << vec1.max_size() << endl;
cout << "vec1.capacity() = " << vec1.capacity() << endl;
cout << "vec1.empty() = " << boolalpha << vec1.empty() << endl;
// 改变大小
vec1.resize(6, u8"a");
for (auto it : vec1)
{
cout << "v1:" << getStringFromU8string(it) << endl;
}
// 设置容量为指定大小(值太大会用默认值填充,值太小会以实际内容个数为准)
vec1.reserve(10);
cout << getStringFromU8string(u8"reserve后, vec1.size() = ") << vec1.size() << endl;
cout << getStringFromU8string(u8"reserve后, vec1.capacity() = ") << vec1.capacity() << endl;
// 设置容量为实际内容个数
vec1.shrink_to_fit();
cout << getStringFromU8string(u8"shrink_to_fit后, vec1.size() = ") << vec1.size() << endl;
cout << getStringFromU8string(u8"shrink_to_fit后, vec1.capacity() = ") << vec1.capacity() << endl;
}
元素访问
| 函数 | 说明 |
|---|---|
operator[] |
访问指定位置元素(不检查越界) |
at() |
访问指定位置元素(越界抛出 std::out_of_range 异常) |
front() |
返回第一个元素 |
back() |
返回最后一个元素 |
data() |
返回指向内部数组首元素的指针 |
int main()
{
system("chcp 65001");
vector<std::u8string> vec1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
cout << "vec1[0] = " << getStringFromU8string(vec1[0]) << endl;
cout << "vec1.at(2) = " << getStringFromU8string(vec1.at(2)) << endl;
cout << "vec1.front() = " << getStringFromU8string(vec1.front()) << endl;
cout << "vec1.back() = " << getStringFromU8string(vec1.back()) << endl;
cout << "*vec1.data() = " << getStringFromU8string(*vec1.data()) << endl;
}
迭代遍历
begin-end与cbegin-cend效果一样
| 迭代器 | 说明 |
|---|---|
begin() / cbegin() |
指向第一个元素(c 版本为 const) |
end() / cend() |
指向最后一个元素的下一个位置 |
rbegin() / crbegin() |
反向迭代器,指向最后一个元素 |
rend() / crend() |
反向迭代器,指向第一个元素的前一个位置 |
int main()
{
system("chcp 65001");
vector<std::u8string> vec1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
// for循环
for (auto it : vec1) {
cout << getStringFromU8string(it) << endl;
}
// begin-end正向遍历
for (auto it = vec1.begin(); it != vec1.end(); it++)
{
cout << "begin-end " << getStringFromU8string(*it) << endl;
}
// cbegin-cend正向遍历
for (auto it = vec1.cbegin(); it != vec1.cend(); it++)
{
cout << "cbegin-cend " << getStringFromU8string(*it) << endl;
}
// rbegin-rend反向遍历
for (auto it = vec1.rbegin(); it != vec1.rend(); it++)
{
cout << "rbegin-rend " << getStringFromU8string(*it) << endl;
}
}
修改操作
| 函数 | 说明 |
|---|---|
push_back(val) |
在末尾添加一个元素 |
pop_back() |
删除最后一个元素 |
insert(pos, val) |
在指定位置插入元素 |
insert(pos, n, val) |
插入 n 个 val |
insert(pos, first, last) |
插入另一个容器的 [first, last) 范围 |
erase(pos) |
删除指定位置的元素 |
erase(first, last) |
删除 [first, last) 范围内的元素 |
clear() |
清空所有元素 |
swap(other) |
与另一个 vector 交换内容 |
int main()
{
system("chcp 65001");
vector<std::u8string> vec1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
vector<std::u8string> vec2 = { u8"张三", u8"李四" };
// 末尾添加一个元素
vec1.push_back(u8"杭州");
cout << getStringFromU8string(u8"push_back后: ");
for (auto it : vec1) {
cout << getStringFromU8string(it) << ", ";
}
cout << endl;
// 删除最后一个元素
vec1.pop_back();
cout << getStringFromU8string(u8"pop_back后: ");
for (auto it : vec1) {
cout << getStringFromU8string(it) << ", ";
}
cout << endl;
// 插入数据
vec1.insert(vec1.begin() + 1, u8"成都");
vec1.insert(vec1.begin() + 1, 2, u8"_");
vec1.insert(vec1.begin(), vec2.begin(), vec2.end());
cout << getStringFromU8string(u8"insert后: ");
for (auto it : vec1) {
cout << getStringFromU8string(it) << ", ";
}
cout << endl;
// 删除指定位置元素
vec1.erase(vec1.begin() + 1);
// [first, last)
vec1.erase(vec1.begin() + 1, vec1.begin() + 4);
cout << getStringFromU8string(u8"erase后: ");
for (auto it : vec1) {
cout << getStringFromU8string(it) << ", ";
}
cout << endl;
// 交换元素
vec1.swap(vec2);
cout << getStringFromU8string(u8"swap后: ");
for (auto it : vec1) {
cout << getStringFromU8string(it) << ", ";
}
cout << endl;
// 清空元素
vec1.clear();
cout << getStringFromU8string(u8"clear后: ");
for (auto it : vec1) {
cout << getStringFromU8string(it) << ", ";
}
cout << endl;
}
注意事项
- 添加数据的时候,如果
size() > capacity()时会触发扩容操作。创建新数组,复制数据,删除旧数据。最好提前设置容量,避免扩容 - 迭代器失效场景(元素增加、减少)
int main()
{
system("chcp 65001");
vector<std::u8string> vec1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
auto it = vec1.begin();
// 末尾添加一个元素
vec1.push_back(u8"杭州");
// 迭代器失效
cout << getStringFromU8string(u8"push_back后: ");
for (; it != vec1.end(); it++)
{
cout << getStringFromU8string(*it) << endl;
}
}
- 与原生数组比较
| 特性 | int arr[10] |
std::vector<int> |
|---|---|---|
| 大小 | 编译时固定 | 运行时可变 |
| 内存 | 栈或静态存储 | 堆(自动管理) |
| 越界检查 | 无 | at() 提供检查 |
| 传递 | 退化为指针 | 可拷贝、赋值 |
| 获取大小 | sizeof(arr)/sizeof(arr[0]) |
size() |
| 推荐程度 | 低(C 风格) | 高(现代 C++) |
更多推荐



所有评论(0)