std::vector
是 C++ 标准库中的一个容器,提供了动态数组的功能。它的底层实现通常是使用连续的内存块来存储元素,因此可以通过指针算术来访问元素,并且支持常数时间的随机访问,并支持在容器末尾高效地添加和删除元素。
一、底层实现
std::vector
的底层通常由一个连续的内存块(数组)来存储其元素,内部的元素在内存中是依次排列的,可以通过指针算术或迭代器进行快速的随机访问。
当 std::vector
中的元素数量超过当前容量时,std::vector
会重新分配更大的内存块,并将元素从旧的内存块复制到新的内存块中。这通常涉及到动态内存分配和释放,但由于 std::vector
使用连续的内存存储元素,因此仅需要一次连续的内存分配,这有助于提高效率。
当创建一个空的 std::vector
对象时,它不分配任何内存,大小是0。当开始添加元素时,std::vector
会动态分配内存。通常情况下,第一次分配的内存大小由具体的实现决定,但通常是一个小的初始值,比如16或32个元素大小的内存块。
当元素数量超过当前内存容量时,std::vector
将重新分配内存并将元素从旧的内存块复制到新的内存块中。新的内存块的大小通常是当前元素数量的两倍或更多,具体取决于具体的实现和策略。重新分配内存时,可能会有一些额外的内存开销,因为需要考虑到内存对齐和内存管理的一些细节。
二、成员函数
std::vector 提供了一系列成员函数来操作和管理动态数组。
1、迭代器:
begin()
, end()
cbegin()
, cend()
rbegin()
, rend()
crbegin()
, crend()
std::vector<int> vec{
1,2,3,4,5};
std::cout<<"begin() -> end()"<<std::endl;
for(auto it = vec.begin(); it != vec.end(); it++) {
std::cout<<*it<<std::endl; // 1 2 3 4 5
}
std::cout<<"cbegin() -> cend()"<<std::endl;
for(auto it = vec.cbegin(); it != vec.cend(); it++) {
std::cout<<*it<<std::endl; // 1 2 3 4 5
}
std::cout<<"rbegin() -> rend()"<<std::endl;
for(auto it = vec.rbegin(); it != vec.rend(); it++) {
std::cout<<*it<<std::endl; // 5 4 3 2 1
}
std::cout<<"crbegin() -> crend()"<<std::endl;
for(auto it = vec.crbegin(); it != vec.crend(); it++) {
std::cout<<*it<<std::endl; // 5 4 3 2 1
}
2、容量:
empty()
size()
max_size()
reserve(size_type new_cap)
capacity()
shrink_to_fit()
std::vector<int> vec{
1,2,3,4,5};
std::cout<<vec.empty()<<std::endl; // 0
std::cout<<vec.size()<<std::endl; // 5
std::cout<<vec.max_size()<<std::endl; // 2305843009213693951
std::cout<<vec.capacity()<<std::endl; // 5
vec.reserve(50);
std::cout<<vec.capacity()<<std::endl; // 50
vec.shrink_to_fit();
std::cout<<vec.capacity()<<std::endl; // 5
resize(size_type count)
resize(size_type count, const value_type& value)
std::vector<int> vec{
1,2,3};
for(auto num:vec){
std::cout<<num<<std::endl; // 1 2 3
}
vec.resize(5);
for(auto num:vec){
std::cout<<num<<std::endl; // 1 2 3 0 0
}
3、元素访问:
operator[]
at()
front()
back()
data()
std::vector<int> vec{
0,1,2,3,4,5};
std::cout<<vec[3]<<std::endl; // 3
std::cout<<vec.at(3)<<std::endl; // 3
std::cout<<vec.front()<<std::endl; // 0
std::cout<<vec.back()<<s