容器库(2)-std::vector

std::vector管理的是动态分配的数组,可以在运行时添加和删除元素。vector管理的底层内存是连续的,当添加元素时没有剩余容量时,vector会重新申请一片新的合适大小的连续内存。

本文章的代码库:

https://gitee.com/gamestorm577/CppStd

成员函数

构造、赋值和析构

构造函数

可以用元素或者另一个vector来构造vector。代码示例:

std::vector<float> v1;
std::vector<float> v2(3, 1.f);
std::vector<float> v3(3);
std::vector<float> v4(v2.begin(), v2.begin() + 2);
std::vector<float> v5(v2);
std::vector<float> tmp(v2);
std::vector<float> v6(std::move(tmp));
std::vector<float> v7{1.f, 2.f, 3.f, 4.f, 5.f};

std::cout << "v1 size = " << v1.size() << std::endl;
std::cout << "v2 size = " << v2.size() << std::endl;
std::cout << "v3 size = " << v3.size() << std::endl;
std::cout << "v4 size = " << v4.size() << std::endl;
std::cout << "v5 size = " << v5.size() << std::endl;
std::cout << "v6 size = " << v6.size() << std::endl;
std::cout << "v7 size = " << v7.size() << std::endl;

输出结果:

v1 size = 0
v2 size = 3
v3 size = 3
v4 size = 2
v5 size = 3
v6 size = 3
v7 size = 5

析构函数

销毁vector时,会从右到左依次调用元素的析构函数。代码示例:

struct MyStruct
{
    ~MyStruct()
    {
        std::cout << "Destruct " << Index << std::endl;
    }

    int Index = 0;
};

std::vector<MyStruct> vec(3);
vec[0].Index = 1;
vec[1].Index = 2;
vec[2].Index = 3;

输出结果:

Destruct 3
Destruct 2
Destruct 1

赋值函数

可以另一个vector或者元素列表给vector赋值。代码示例:

std::vector<int> tmp{1, 2, 3, 4};
std::vector<int> vec1;
std::vector<int> vec2;
std::vector<int> vec3;

vec1 = tmp;
vec2 = std::move(tmp);
vec3 = {1, 2, 3, 4, 5};
std::cout << "vec1 size = " << vec1.size() << std::endl;
std::cout << "vec2 size = " << vec2.size() << std::endl;
std::cout << "vec3 size = " << vec3.size() << std::endl;

输出结果:

vec1 size = 4
vec2 size = 4
vec3 size = 5

assign

可以用元素、元素列表和迭代器给vector赋值,vector原来的内容将被替换。代码示例:

std::vector<float> vec = {1.f, 2.f, 3.f, 4.f, 5.f};
std::vector<float> tmp = {1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f};

vec.assign(3, 5.f);
std::cout << "vec size = " << vec.size() << std::endl;
vec.assign(tmp.begin(), tmp.begin() + 7);
std::cout << "vec size = " << vec.size() << std::endl;
vec.assign({1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f});
std::cout << "vec size = " << vec.size() << std::endl;

输出结果:

vec size = 3
vec size = 7
vec size = 8

元素访问

at

返回指定位置的元素的引用,如果超出边界,会抛出异常。代码示例:

std::vector<float> vec = {1.f, 2.f, 3.f, 4.f, 5.f};
float& num = vec.at(3);
std::cout << "vec at 3 is: " << vec.at(3) << std::endl;

输出结果:

vec at 3 is: 4

operator[]

返回指定位置的元素的引用,没有边界检查。代码示例:

std::vector<float> vec = {1.f, 2.f, 3.f, 4.f, 5.f};
float& num = vec[3];
std::cout << "vec at 3 is: " << vec[3] << std::endl;

输出结果:

vec at 3 is: 4

front

返回首个元素的引用,要求array不为空。代码示例:

std::vector<float> vec = {1.f, 2.f, 3.f, 4.f, 5.f};
float& num = vec.front();
num = 5.4f;
std::cout << "vec front is: " << vec.front() << std::endl;

输出结果:

vec front is: 5.4

back

返回最后一个元素的引用,要求array不为空。代码示例:

std::vector<float> vec = {1.f, 2.f, 3.f, 4.f, 5.f};
float& num = vec.back();
num = 11.4f;
std::cout << "vec back is: " << vec.back() << std::endl;

输出结果:

vec back is: 11.4

data

返回保存内存的底层地址,底层是一片连续的内存。代码示例:

std::vector<float> vec = {1.f, 2.f, 3.f, 4.f, 5.f};
float* data = vec.data();
*(data + 3) = 23.5f;
std::cout << "vec at 3 is: " << vec.at(3) << std::endl;

输出结果:

vec at 3 is: 23.5

迭代器

接口begin、cbegin指向vector起始的迭代器,end、cend指向末尾的迭代器。rbegin、crbegin指向起始的逆向迭代器,rend、crend指向末尾的逆向迭代器。代码示例:

std::vector<float> vec = {1.f, 2.f, 3.f, 4.f, 5.f};
for (auto iter = vec.rbegin(); iter != vec.rend(); ++iter)
{
    *iter += 10.1f;
}

for (auto iter = vec.crbegin(); iter != vec.crend(); ++iter)
{
    std::cout << "num = " << *iter << std::endl;
}

输出结果:

num = 15.1
num = 14.1
num = 13.1
num = 12.1
num = 11.1

容量

empty

检查容器的元素是否为空。代码示例:

std::vector<float> vec1 = {1.f, 2.f, 3.f, 4.f, 5.f};
std::vector<float> vec2;

std::cout << std::boolalpha;
std::cout << "vec1 empty: " << vec1.empty() << std::endl;
std::cout << "vec2 empty: " << vec2.empty() << std::endl;

输出结果:

vec1 empty: false
vec2 empty: true

size

返回vector中元素的个数。代码示例:

std::vector<float> vec1 = {1.f, 2.f, 3.f, 4.f, 5.f};
std::vector<float> vec2;
std::cout << "vec1 size = " << vec1.size() << std::endl;
std::cout << "vec2 size = " << vec2.size() << std::endl;

输出结果:

vec1 size = 5
vec2 size = 0

max_size

返回系统支持的vector元素最大个数。代码示例:

std::vector<float> vec1 = {1.f, 2.f, 3.f, 4.f, 5.f};
std::cout << "max size of vector is: " << vec1.max_size() << std::endl;

可能的输出结果:

max size of vector is: 4611686018427387903

capacity

获取vector当前可以容纳的元素个数,大于等于当前vector拥有的元素个数。代码示例:

std::vector<float> vec = {1.f, 2.f, 3.f, 4.f, 5.f};
vec = {1.f, 2.f, 3.f};
std::cout << "vec size is: " << vec.size() << std::endl;
std::cout << "vec capicity is: " << vec.capacity() << std::endl;

输出结果:

vec size is: 3
vec capicity is: 5

reserve

让vector分配新的容量大小,如果新的容量比当前vector的容量小,那么不做任何操作,否则将重新分配新的空间大小。代码示例:

std::vector<float> vec(20, 1.f);
vec = {1.f, 2.f, 3.f};
std::vector<float>::size_type new_capacity = 0;
std::cout << "vec size is: " << vec.size() << ", capacity is: " << vec.capacity() << std::endl;

new_capacity = vec.capacity() - 5;
vec.reserve(new_capacity);
std::cout << "vec size is: " << vec.size() << ", capacity is: " << vec.capacity() << std::endl;

new_capacity = vec.capacity() + 20;
vec.reserve(new_capacity);
std::cout << "vec size is: " << vec.size() << ", capacity is: " << vec.capacity() << std::endl;

输出结果:

vec size is: 3, capacity is: 20
vec size is: 3, capacity is: 20
vec size is: 3, capacity is: 40

shrink_to_fit

请求删除空闲的空间,具体是否移除依赖于实现。代码示例:

std::vector<float> vec(20, 1.f);
vec = {1.f, 2.f, 3.f};
std::cout << "vec size is: " << vec.size() << ", capacity is: " << vec.capacity() << std::endl;
vec.shrink_to_fit();
std::cout << "vec size is: " << vec.size() << ", capacity is: " << vec.capacity() << std::endl;

输出结果:

vec size is: 3, capacity is: 20
vec size is: 3, capacity is: 3

修改器

clear

清除vector中的所有元素,该操作不会改变vector的容量。代码示例:

std::vector<float> vec(20, 1.f);
std::cout << "vec size is: " << vec.size() << ", capacity is: " << vec.capacity() << std::endl;
vec.clear();
std::cout << "vec size is: " << vec.size() << ", capacity is: " << vec.capacity() << std::endl;

输出结果:

vec size is: 20, capacity is: 20
vec size is: 0, capacity is: 20

insert

在指定位置插入元素,可以插入元素、元素列表、vector或者迭代器。代码示例:

auto print_func = [](const std::vector<float> vec) -> void
{
    for (auto i : vec)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<float> vec1(4, 1.1f);
vec1.insert(vec1.begin() + 2, 5.5f);
print_func(vec1);

std::vector<float> vec2(4, 1.1f);
vec2.insert(vec2.begin() + 2, 5, 5.5f);
print_func(vec2);

std::vector<float> tmp{1.1f, 2.2f, 3.3f};
std::vector<float> vec3(4, 1.1f);
vec3.insert(vec3.begin() + 2, tmp.begin(), tmp.end());
print_func(vec3);

std::vector<float> vec4(4, 1.1f);
vec4.insert(vec4.begin() + 2, {10.1f, 10.2f, 10.3f});
print_func(vec4);

输出结果:

1.1 1.1 5.5 1.1 1.1 
1.1 1.1 5.5 5.5 5.5 5.5 5.5 1.1 1.1 
1.1 1.1 1.1 2.2 3.3 1.1 1.1 
1.1 1.1 10.1 10.2 10.3 1.1 1.1 

 emplace

在指定位置插入一个元素。示例代码:

std::vector<float> vec(4, 1.1f);
vec.emplace(vec.begin() + 1, 15.5f);
for (auto i : vec)
{
    std::cout << i << " ";
}
std::cout << "\n";

输出结果:

1.1 15.5 1.1 1.1 1.1 

erase

擦除指定位置的元素。示例代码:

auto print_func = [](const std::vector<float> vec) -> void
{
    for (auto i : vec)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<float> vec{1.5, 2.5, 3.5, 4.5, 5.5f, 6.5f, 7.5f, 8.5f};
print_func(vec);
vec.erase(vec.begin() + 1);
print_func(vec);
vec.erase(vec.begin() + 1, vec.begin() + 5);
print_func(vec);

输出结果:

1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 
1.5 3.5 4.5 5.5 6.5 7.5 8.5 
1.5 7.5 8.5 

push_back

在vector末尾添加一个元素。代码示例:

struct MyStruct
{
};

MyStruct tmp;
std::vector<MyStruct> vec;
vec.push_back(tmp);
vec.push_back(std::move(tmp));
std::cout << "vec size = " << vec.size() << std::endl;

输出结果:

vec size = 2

emplace_back

在vector末尾构造一个元素。代码示例:

struct MyStruct
{
    MyStruct(std::string str, float num)
        : Str(str)
        , Num(num)
    {
    }

    std::string Str;
    float Num;
};

std::vector<MyStruct> vec;
vec.emplace_back("hello", 1.5f);
vec.emplace_back("world", 10.5f);
for (auto& i : vec)
{
    std::cout << "str = " << i.Str << ", num = " << i.Num << "\n";
}

输出结果:

str = hello, num = 1.5
str = world, num = 10.5

pop_back

移除vector末尾的元素。代码示例:

std::vector<int> vec = {1, 2, 3, 4, 5};
vec.pop_back();
vec.pop_back();
std::cout << "vec size = " << vec.size() << std::endl;

输出结果:

vec size = 3

resize

重新设置vector元素的个数,如果个数大于vector容量的大小,vector将重新分配空间。代码示例:

std::vector<float> vec(20, 4.f);
vec = {1.f, 2.f, 3.f, 4.f};
std::cout << "s = " << vec.size() << ", cap = " << vec.capacity() << "\n";
vec.resize(10);
std::cout << "s = " << vec.size() << ", cap = " << vec.capacity() << "\n";
vec.resize(2);
std::cout << "s = " << vec.size() << ", cap = " << vec.capacity() << "\n";
vec.resize(25);
std::cout << "s = " << vec.size() << ", cap = " << vec.capacity() << "\n";

输出结果:

s = 4, cap = 20
s = 10, cap = 20
s = 2, cap = 20
s = 25, cap = 40

swap

和另一个vector交换元素。代码示例:

std::vector<float> vec1(20, 4.f);
std::vector<float> vec2(5, 4.f);
vec1.swap(vec2);
std::cout << "vec1 size = " << vec1.size() << std::endl;
std::cout << "vec2 size = " << vec2.size() << std::endl;

输出结果:

vec1 size = 5
vec2 size = 20

非成员函数

比较运算符

operator==,!=,<,<=,>,>=用于比较两个vector。代码示例:

std::vector<int> vec1{1, 2, 3};
std::vector<int> vec2{11, 12, 13, 14};
std::cout << std::boolalpha;
std::cout << "vec1 == vec2: " << (vec1 == vec2) << std::endl;
std::cout << "vec1 != vec2: " << (vec1 != vec2) << std::endl;
std::cout << "vec1 <  vec2: " << (vec1 < vec2) << std::endl;
std::cout << "vec1 <= vec2: " << (vec1 <= vec2) << std::endl;
std::cout << "vec1 >  vec2: " << (vec1 > vec2) << std::endl;
std::cout << "vec1 >= vec2: " << (vec1 >= vec2) << std::endl;

输出结果:

vec1 == vec2: false
vec1 != vec2: true
vec1 <  vec2: true
vec1 <= vec2: true
vec1 >  vec2: false
vec1 >= vec2: false

std::swap

交换两个vector的内容。代码示例:

std::vector<float> vec1(20, 4.f);
std::vector<float> vec2(5, 4.f);
std::swap(vec1, vec2);
std::cout << "vec1 size = " << vec1.size() << std::endl;
std::cout << "vec2 size = " << vec2.size() << std::endl;

输出结果:

vec1 size = 5
vec2 size = 20

erase、erase_if

erase删除等于指定值的元素,erase_if删除满足要求的元素。代码示例:

auto print_func = [](const std::vector<int> vec) -> void
{
    for (auto i : vec)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<int> vec = {1, 2, 2, 3, 4, 4, 4, 5, 8, 8, 9, 9, 9};
print_func(vec);

std::erase(vec, 4);
print_func(vec);

std::erase_if(vec,
              [](int x) -> bool
              {
                  return x > 7;
              });
print_func(vec);

输出结果:

1 2 2 3 4 4 4 5 8 8 9 9 9 
1 2 2 3 5 8 8 9 9 9 
1 2 2 3 5 

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值