菜鸟笔记
提升您的技术认知

std::vector

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

起始