c++中vector的使用优化

文章是参考了Cherno大神的C++视频做的总结

有这么一段c++代码,如下:

样例代码

#include<iostream>
#include<vector>
struct Vertex{
    float x,y,z;
    Vertex(float x,float y,float z)
    :x(x),y(y),z(z)
    {
    }

    Vertex(const Vertex& Vertex)
    :x(Vertex.x),y(Vertex.y),z(Vertex.z)
    {
        std::cout<<"Vertex被Copy了一次"<<std::endl;
    }
};

int main(){
    std::vector<Vertex> Vertices;
    Vertices.push_back({1,2,3});
    Vertices.push_back({4,5,6});
    Vertices.push_back({7,8,9});


    return 0;
}

其中这一段是拷贝构造函数,不懂的可以参考文章c++拷贝构造函数

Vertex(const Vertex& Vertex)
    :x(Vertex.x),y(Vertex.y),z(Vertex.z)
    {
        std::cout<<"Vertex被Copy了一次"<<std::endl;
    }

当运行上面代码的时候,会得到以下输出

可以发现"Vertex被Copy了一次"被打印了六次。这是为什么?

这是因为每次push_back会构造一个临时Vertex对象,随后调用拷贝构造函数将其复制到vector中。

拷贝次数计算

  • 第一次push_back
    • 构造临时对象(无输出)。
    • 拷贝到vector(1次拷贝)。
  • 第二次push_back
    • 构造临时对象(无输出)。
    • 扩容至2,拷贝旧元素(1次)。
    • 拷贝临时对象(1次)。
    • 总计2次
  • 第三次push_back
    • 构造临时对象(无输出)。
    • 扩容至4,拷贝前两个元素(2次)。
    • 拷贝临时对象(1次)。
    • 总计3次
  • 总拷贝次数:1 + 2 + 3 = 6次,输出6次"Vertex被Copy了一次"。

这段代码在向std::vector添加元素时存在不必要的拷贝操作,导致性能下降。

接下来讲解如何优化。

优化

优化建议

使用emplace_back替代push_back:直接在vector内存中构造对象,避免临时对象拷贝。
Vertices.emplace_back(1, 2, 3);  // 无需拷贝,直接构造
预分配内存reserve():避免动态扩容时的多次拷贝。
std::vector<Vertex> Vertices;
Vertices.reserve(3);  // 预分配足够空间
添加移动构造函数(可选):若元素需频繁转移,定义移动语义提升效率。
Vertex(Vertex&&) = default;  // 显式默认移动构造函数

以下是优化后的代码:

#include<iostream>
#include<vector>
struct Vertex{
    float x,y,z;
    Vertex(float x,float y,float z)
    :x(x),y(y),z(z)
    {}

    Vertex(const Vertex& other)
    :x(other.x),y(other.y),z(other.z)
    {
        std::cout << "Vertex被Copy了一次" << std::endl;
    }
};

int main(){
    std::vector<Vertex> Vertices;
    Vertices.reserve(3);  // 预分配内存,避免扩容

    Vertices.emplace_back(1, 2, 3);  // 直接构造,无拷贝
    Vertices.emplace_back(4, 5, 6);
    Vertices.emplace_back(7, 8, 9);

    return 0;
}

可以看到就没有打印"Vertex被Copy了一次"了,说明没有拷贝构造函数的调用。

优化讲解

push_back和emplace_back有什么区别?

C++中push_back和emplace_back有什么区别?

vertices.reserve(3);和std::vector<Vertex> vertices(3);有什么区别?
  • vertices.reserve(3);:该语句是针对已经存在的 std::vector 对象 vertices 进行操作。它的主要功能是为 vector 预先分配足够存储3个 Vertex 类型元素的内存空间,但并不会创建实际的元素。也就是说,此时 vector 的大小(size())仍然为0,只是容量(capacity())变为了3。
  • std::vector<Vertex> vertices(3);:这是在声明并初始化 std::vector 对象 vertices。它会直接创建一个包含3个 Vertex 类型元素的 vector,每个元素都会调用 Vertex 类的默认构造函数进行初始化。此时 vector 的大小(size())和容量(capacity())都为3。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值