std::vector
介绍
成员函数
- 构造析构
- 元素访问
- 迭代器
- 容量
- 修改器
非成员函数
介绍
// vector 模板定义
template<class T, class Allocator = std::allocator<T> > class vector;
namespace pmr { // c++17 起
template <class T>
using vector = std::vector<T, std::pmr::polymorphic_allocator<T>>;
}
- vector 介绍摘选自 cppreference.com 中文网 vector 介绍
- T 必须满足可复制赋值 (CopyAssignable) 和可复制构造 (CopyConstructible) 的要求(C++11 前),泛言之,要求元素类型是完整类型并满足可擦除 (Erasable) 的要求,但许多成员函数附带了更严格的要求 (C++11 起)
- Allocator 动态获取/释放内存及构造/析构内存中元素的分配器,若Allocator::value_type 与 T 不同则行为未定义
- 包含在头文件 vector 中,可以理解为动态数组,其内存是动态增长的,当空间不够存储时自动分配内存,分配策略不同编译器实现可能不同,但绝对不是用多少分配多少,这样效率不高
- 元素是连续存储的,访问元素可以通过迭代器和指针
- 随机访问复杂度 O(1),在末尾插入或移除元素 O(1),插入或移除元素,与到 vector 结尾的距离成线性 O(n)
- std::vector (对于 bool 以外的 T )满足容器 (Container) 、知分配器容器 (AllocatorAwareContainer) 、序列容器 (SequenceContainer) 、连续容器 (ContiguousContainer) (C++17 起)及可逆容器 (ReversibleContainer) 的要求元素的类型
成员函数
构造析构
#include <vector>
int main()
{
auto Print = [](const std::string&msg, const std::vector<int>& vec) { // 打印
std::cout << msg << " : ";
for (int val : vec)
std::cout << val << "\t";
std::cout << "\n";
};
std::vector<int> vec1; // 默认无参构造
Print("vec1", vec1);
std::allocator<int> alloc2;
std::vector<int> vec2(alloc2); // 指定分配器
Print("vec2", vec2);
std::vector<int> vec3(5, 10); // 初始化 5 个元素,每个元素初始化值为 10
Print("vec3", vec3);
std::vector<int> vec4(5); // 初始化 5 个元素,每个元素初始化值为 0
Print("vec4", vec4);
std::vector<int>::iterator itBegin = vec3.begin();
std::vector<int>::iterator itEnd = vec3.end();
std::vector<int> vec5(itBegin, itEnd); // 迭代器初始化
Print("vec5", vec5);
std::vector<int> vec6(vec5); // 拷贝构造
Print("vec6", vec6);
std::vector<int> vec7(vec6, alloc2); // 拷贝构造,指定分配器类型
Print("vec7", vec7);
std::vector<int> vec8(std::move(vec5)); // 移动构造
Print("vec8", vec8);
std::vector<int> vec9(std::move(vec6), alloc2); // 移动构造,指定分配器类型
Print("vec9", vec9);
std::vector<int> vec10{1,2,3,4,5}; // 初始化列表
Print("vec10", vec10);
// ~vector(); 默认析构函数
return 0;
}
输出结果:
vec1 :
vec2 :
vec3 : 10 10 10 10 10
vec4 : 0 0 0 0 0
vec5 : 10 10 10 10 10
vec6 : 10 10 10 10 10
vec7 : 10 10 10 10 10
vec8 : 10 10 10 10 10
vec9 : 10 10 10 10 10
vec10 : 1 2 3 4 5
元素访问
#define COUT(msg, x) std::cout<<std::string(msg)<<"\t"<<int(x)<<std::endl;
int main()
{
std::vector<int> vec{1,2,3,4,5}; // 初始化列表
COUT("vec.at(0) : ", vec.at(0)); // 访问指定下标的元素,同时进行越界检查
COUT("vec[2] : ", vec[2]); // 访问指定下标的元素
COUT("vec.front() : ", vec.front()); // 访问第一个元素
COUT("vec.back() : ", vec.back()); // 访问最后一个元素
COUT("*vec.data() : ", *vec.data()); // 返回指向内存中数组第一个元素的指针
return 0;
}
输出结果:
vec.at(0) : 1
vec[2] : 3
vec.front() : 1
vec.back() : 5
*vec.data() : 1
迭代器
int main()
{
std::vector<int> vec{1,2,3,4,5}; // 初始化列表
std::vector<int>::iterator iter = vec.begin(); // 返回指向起始的迭代器,读写迭代器
for (; iter != vec.end(); ++iter) {
std::cout << *iter << "\t";
}
std::cout << "\n";
std::vector<int>::const_iterator citer = vec.cbegin();// 返回指向起始的迭代器,只读迭代器
for (; citer != vec.cend(); ++citer) {
std::cout << *citer << "\t";
}
std::cout << "\n";
std::vector<int>::reverse_iterator riter = vec.rbegin();// 逆向返回指向起始的迭代器,读写迭代器
for (; riter != vec.rend(); ++riter) {
std::cout << *riter << "\t";
}
std::cout << "\n";
std::vector<int>::const_reverse_iterator criter = vec.crbegin();// 逆向返回指向起始的迭代器,只读迭代器
for (; criter != vec.crend(); ++criter) {
std::cout << *criter << "\t";
}
std::cout << "\n";
return 0;
}
输出结果:
1 2 3 4 5
1 2 3 4 5
5 4 3 2 1
5 4 3 2 1
容量
int main()
{
std::vector<int> vec{1,2,3,4,5}; // 初始化列表
std::cout << std::boolalpha << "vec.empty() : " << vec.empty() << "\n"; // 是否为空
std::cout << "vec.size() : " << vec.size() << "\n"; // 容器元素数量
std::cout << "vec.max_size() : " << vec.max_size() << "\n"; // 容器可容纳的最大数量,和平台相关
std::cout << "vec.capacity() : " << vec.capacity() << "\n"; // 容器容量 >= 容器元素数量
vec.reserve(20); // 容器预留空间
std::cout << "vec.capacity() : " << vec.capacity() << "\n";
vec.shrink_to_fit(); // 通过释放未使用的内存减少内存的使用
std::cout << "vec.capacity() : " << vec.capacity() << "\n";
return 0;
}
输出结果:
vec.empty() : false
vec.size() : 5
vec.max_size() : 4611686018427387903
vec.capacity() : 5
vec.capacity() : 20
vec.capacity() : 5
修改器
int main()
{
auto Print = [](const std::string&msg, const std::vector<int>& vec) { // 打印
std::cout << msg << " : ";
for (int val : vec)
std::cout << val << "\t";
std::cout << "\n";
};
std::vector<int> vec{1,2,3,4,5}; // 初始化列表
Print("origin vec", vec);
vec.clear(); // 清除容器
Print("vec.clear", vec);
vec.insert(vec.begin(), {1,2,3,4,5}); // 插入元素,insert 函数有好几个重载函数
Print("vec.insert", vec);
vec.emplace(vec.end(), 6); // 原位构造元素
Print("vec.emplace", vec);
vec.erase(vec.begin(), vec.begin() + 1); // 擦除元素
Print("vec.erase", vec);
vec.push_back(7); // 将元素添加到容器末尾
Print("vec.push_back", vec);
vec.emplace_back(8); // 在容器末尾就地构造元素
Print("vec.emplace_back", vec);
vec.pop_back(); // 移除末尾元素
Print("vec.pop_back", vec);
vec.resize(2); // 改变容器中可存储元素的个数
Print("vec.resize", vec);
std::vector<int> vec2;
vec2.swap(vec);
Print("vec2", vec2);
Print("vec", vec);
return 0;
}
输出结果:
origin vec : 1 2 3 4 5
vec.clear :
vec.insert : 1 2 3 4 5
vec.emplace : 1 2 3 4 5 6
vec.erase : 2 3 4 5 6
vec.push_back : 2 3 4 5 6 7
vec.emplace_back : 2 3 4 5 6 7 8
vec.pop_back : 2 3 4 5 6 7
vec.resize : 2 3
vec2 : 2 3
vec :
非成员函数
int main()
{
auto Print = [](const std::string&msg, const std::vector<int>& vec) { // 打印
std::cout << msg << " : ";
for (int val : vec)
std::cout << val << "\t";
std::cout << "\n";
};
std::vector<int> vec1{1,2,3,4,5}; // 初始化列表
std::vector<int> vec2{1,2,3,4,6};
std::cout << std::boolalpha << "vec1 == vec2 : " << (vec1 == vec2) << "\n";
std::cout << std::boolalpha << "vec1 != vec2 : " << (vec1 != vec2) << "\n";
std::cout << std::boolalpha << "vec1 > vec2 : " << (vec1 > vec2) << "\n";
std::cout << std::boolalpha << "vec1 >= vec2 : " << (vec1 >= vec2) << "\n";
std::cout << std::boolalpha << "vec1 < vec2 : " << (vec1 < vec2) << "\n";
std::cout << std::boolalpha << "vec1 <= vec2 : " << (vec1 <= vec2) << "\n";
std::vector<int> vec3;
std::swap(vec1, vec3); // 交换元素
Print("vec1", vec1);
Print("vec3", vec3);
return 0;
}
输出结果:
vec1 == vec2 : false
vec1 != vec2 : true
vec1 > vec2 : false
vec1 >= vec2 : false
vec1 < vec2 : true
vec1 <= vec2 : true
vec1 :
vec3 : 1 2 3 4 5
起始