C++的vector使用优化

我们在上一章说了如何使用这个vector动态数组,这章我们说说如何更好的使用它以及它是如何工作的。当你创建一个vector,然后使用push_back添加元素,当当前的vector的内存不够时,会从内存中的旧位置复制到内存中的新位置,然后删除删除旧位置的内存,也就是说当我push_back,vector容量不够添加元素就会调整大小,重新分配,这也就是将代码拖慢的原因之一。是事实,我们需要不断的重新分配,这是一个非常缓慢的操作,应该避免。我们如何避免复制对象,如果我们处理的是vector,特别是基于vector的对象,我们没有存储vector指针,我们存储的是vector对象,那占的内存就更大了,所以我们要优化复制。

#include <iostream>
#include <string>
#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 << "Copied!" << std::endl;
	}
};

int main()
{
	std::vector<Vertex> vertices;
    //打印6次
	//vertices.push_back(Vertex(1, 2, 3));
	//vertices.push_back(Vertex(4, 8, 9));
	//vertices.push_back(Vertex(7, 5, 6));

    //打印3次
	vertices.reserve(3);
	vertices.push_back(Vertex(1, 2, 3));
	vertices.push_back(Vertex(4, 8, 9));
	vertices.push_back(Vertex(7, 5, 6));
	std::cin.get();

    //打印0次
    vertices.emplace_back(1, 2, 3);
	vertices.emplace_back(14, 4, 6);
	vertices.emplace_back(7, 8, 9);

}

在上面这段代码中,我们复制了6次(调用了6次拷贝构造函数),这个是为什么呢?当我们在push_back的时候,我们实际是在,主函数的当前帧中构造它,所以我们在main的栈上创建它,然后我们需要做的是,把它放到这个vector中,所以我们是从main函数中(把这个创建的vertex)放到实际的vector中。

在 C++ 中,std::vector 是一个动态数组,它可以调整其大小以容纳不同数量的元素。当你调用 reserve 方法时,你告诉 vector 它应该预先分配足够的内存来存储指定数量的元素,但并不会真正添加这些元素。这样做的好处是,当你稍后添加元素到 vector 时,它可能不需要重新分配内存(如果添加的元素数量没有超过预留的数量),这可以提高效率,因为内存分配通常是一个昂贵的操作。

在我们的代码中,由于预留了 3 个元素的空间,因此当你添加前三个元素时,不需要重新分配内存,所以不会调用拷贝构造函数(除了可能的隐式移动构造函数或复制省略,但这些在这个例子中都不适用,因为直接传递了临时对象)。但是,如果你没有调用 reserve,并且 vector 的初始容量小于你要添加的元素数量,那么在添加元素时可能需要重新分配内存。在重新分配内存时,旧的元素会被拷贝(或移动)到新的内存位置,这就会调用拷贝构造函数(或移动构造函数)。

当你使用 vertices.emplace_back(1, 2, 3);(以及类似的 emplace_back 调用)时,你实际上是在告诉 std::vector 直接在其内部存储中构造 Vertex 对象,而不是先创建一个临时对象然后再将其拷贝或移动到 vector 中。这是 emplace_back 相较于 push_back 的主要优势之一,因为它避免了不必要的拷贝或移动操作,从而提高了效率。

由于 emplace_back 直接在 vector 的内存中构造对象,它不会调用 Vertex 的拷贝构造函数。相反,它会调用 Vertex 的构造函数,直接传递参数给构造函数来构造对象。这就是为什么你在使用 emplace_back 后没有看到 "Copied!" 的输出。而是三次Constructed!

#include <iostream>
#include <string>
#include <vector>

struct Vertex
{
	float x, y, z;

	Vertex(float x, float y, float z)
		: x(x), y(y), z(z)
	{
		std::cout << "Constructed!" << std::endl;
	}
	//拷贝构造
	Vertex(const Vertex& vertex)
		: x(vertex.x), y(vertex.y), z(vertex.z)
	{
		std::cout << "Copied!" << std::endl;
	}
};

int main()
{
	std::vector<Vertex> vertices;
	vertices.reserve(3);

	vertices.emplace_back(1, 2, 3);
	vertices.emplace_back(14, 4, 6);
	vertices.emplace_back(7, 8, 9);
	std::cin.get();
}

运行上述代码,你会看到 "Constructed!" 被打印了3次,而不是 "Copied!",因为 emplace_back 直接在 vector 的内存中构造了 Vertex 对象。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/676160.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pytorch+YOLOv8-1

1.工具开发 2.idea配置pytorch环境 默认安装新版本torch pip install torch 3.pytorch验证 4. print(torch.cuda.is_available()) 输出结果为 False 说明我只能用cpu

【动手学深度学习】softmax回归的简洁实现详情

目录 &#x1f30a;1. 研究目的 &#x1f30a;2. 研究准备 &#x1f30a;3. 研究内容 &#x1f30d;3.1 softmax回归的简洁实现 &#x1f30d;3.2 基础练习 &#x1f30a;4. 研究体会 &#x1f30a;1. 研究目的 理解softmax回归的原理和基本实现方式&#xff1b;学习如何…

prometheus+alertmanager+webhook钉钉机器人告警

版本&#xff1a;centos7.9 python3.9.5 alertmanager0.25.0 prometheus2.46.0 安装alertmanager prometheus 配置webhook # 解压&#xff1a; tar -xvf alertmanager-0.25.0.linux-amd64.tar.gz tar -xvf prometheus-2.46.0.linux-amd64.tar.gz mv alertmanager-0.25.0.linu…

分享毕业论文要怎么写以及写论文工具推荐

毕业论文的写作是一个系统且需要深度研究的过程。以下将分步介绍毕业论文的写作方法&#xff0c;并推荐一些实用的写作工具。 毕业论文写作方法 选题&#xff1a; 确定研究方向和目标&#xff0c;选择具体且有一定研究价值的课题。建议选择应用型题目&#xff0c;结合理论和实…

【HarmonyOS】鸿蒙系统中应用权限等级介绍、定义、申请授权讲解

【HarmonyOS】鸿蒙系统中应用权限等级介绍、定义、申请授权讲解 针对权限等级&#xff0c;相对于主体来说&#xff0c;会有不同的细分概念。 一、权限APL等级&#xff1a; 首先在鸿蒙系统中&#xff0c;对于权限本身&#xff0c;分为三个等级&#xff1a;normal&#xff0c;s…

【JAVA WEB实用与优化技巧】如何使用本地.bat/.sh脚本快速将服务发布到测试环境?

文章目录 普通方式的springboot 使用docker打包发布【手动构建镜像模式】1. maven 打包可运行jar包2.手动打包镜像3.运行容器 全自动化本地命令发布到远程服务的方式配置ssh信任公钥获取公钥git 获取公钥方式: 桌面右键 -> open git gui here -> help -> show SSH key…

【数据库】MySQL表的操作

目录 一.创建表 二.查看表 三.修改表 四.删除表 一.创建表 基本语法&#xff1a; CREATE TABLE table_name(field1 datatype,field2 datatype,field3 datatype) character set 字符集 collate 校验规则 engine 储存引擎field表示列名 datatype表示列的类型 charatcer se…

初识C++ · 模拟实现stack和Queue

目录 前言&#xff1a; 1 Stack 1.1 双端队列 2 Queue 前言&#xff1a; 经历了list三个自定义类型的洗礼&#xff0c;来个简单的放松放松&#xff0c;即栈和队列&#xff1a; 文档记录的&#xff0c;栈和队列是一种容器适配器&#xff0c;它们不属于stl&#xff0c;但是它…

什么是云渲染?怎么使用呢?手把手教你

云渲染是一种利用云计算技术进行图形渲染的服务。它允许用户将渲染任务提交到云端服务器&#xff0c;由远程的计算机集群资源进行渲染操作&#xff0c;完成后再将渲染结果返回给用户。 云渲染技术的优势在于它可以提高渲染效率和质量&#xff0c;支持多任务同时加速渲染&#…

一个被无数人忽视的好项目

这个项目相信大家都在各大短视频平台见过&#xff0c;之前被我忽视了&#xff0c;当时的我自以为它是一时的热度&#xff0c;很快就会凉凉。但现在却生生被打脸了&#xff0c;这其实是非常好变现且流量也很大的一个好项目。 到底是什么好项目呢&#xff0c;没错&#xff0c;就…

[MYSQL]合作过至少三次的演员和导演

ActorDirector 表&#xff1a; ---------------------- | Column Name | Type | ---------------------- | actor_id | int | | director_id | int | | timestamp | int | ---------------------- timestamp 是这张表的主键(具有唯一值的列).编写解决方案…

黑马程序员——Spring框架——day04——SpringMVC基础

目录&#xff1a; SpringMVC简介 背景SpringMVC概述技术体系定位快速入门 目的需求步骤代码实操测试工具 PostMan简介PostMan安装PostMan使用知识点总结请求与参数处理 请求路径 环境准备问题分析解决方式请求方式 环境准备技术分析参数 基本数据类型POJO嵌套POJO数组集合&…

基于卷积神经网络(CNN)的深度迁移学习在声发射(AE)监测螺栓连接状况的应用

螺栓结构在工业中用于组装部件&#xff0c;它们在多种机械系统中扮演着关键角色。确保这些连接结构的健康状态对于航空航天、汽车和建筑等各个行业至关重要&#xff0c;因为螺栓连接的故障可能导致重大的安全风险、经济损失、性能下降和监管合规问题。 在早期阶段检测到螺栓松动…

四、利用启发式算法进行特定数据集的残差网络结构搜索【框架+源码】

背景&#xff1a;工作之后干的事情跟算法关联甚少&#xff0c;整理下读书期间的负责和参与的work&#xff0c;再熟悉学习下。 边熟悉边整理喽~ CV Tradictional workCV AI based work机械臂视觉抓取项目机器学习全流程 Pipeline训练平台OCR生产线喷码识别三维重建(SfM)ROS机器人…

springboot项目通过jar包部署到服务器

1. 将springboot项目打包成jar包 方式一&#xff1a;IDEA为例 出现 BUILD SUCCESS 证明打包成功&#xff0c;自动生成了 target 目录&#xff0c; jar 包就在目录里边 方式二&#xff1a;命令行&#xff08;得配置好maven环境变量&#xff09; 切换到项目目录下&#xff0c;…

springboot管理的各依赖版本查看

找一个springboot相关的依赖&#xff0c;比如这里我找mybatis 鼠标点击artifactId名称&#xff0c;图中蓝色字段&#xff0c;跳转到springboot依赖&#xff08;鼠标悬停在上面变成蓝色表示可点击跳转&#xff09;&#xff0c; 点击spring-boot-dependencites&#xff0c;跳转到…

基于FPGA的SystemVerilog练习

文章目录 一、认识SystemVerilogSystemVerilog的语言特性SystemVerilog的应用领域SystemVerilog的优势SystemVerilog的未来发展方向 二、流水灯代码流水灯部分testbench仿真文件 三、用systemVerilog实现超声波测距计时器测距部分led部分数码管部分采样部分顶层文件引脚绑定效果…

QT入门知识回顾

1 QT简介 1.1 Qt模块: Qt Core模块: 是QT类库的核心&#xff0c;所有其他模块都依赖这个模块 Qt Gui模块: 提供GUI程序的基本功能 Qt Network模块:提供跨平台的网络功能 Qt Widgets模块:提供创建用户界面的功能 1.2Qt的signal/slot机制 任何一个类只要类体前部书写 Q_OBJ…

TH方程学习 (6)

一、内容介绍 本节旨在使用优化算法的方法&#xff0c;旨在利用最小的燃耗实现目标的交会&#xff0c;变量为目标的转移时间。整个问题描述为&#xff1a; 本节拟采取粒子群优化的算法&#xff0c;matlab中自带的粒子群函数为particleswarm&#xff0c;其用法不详细介绍&#…

LeetCode:环形链表II

文章收录于LeetCode专栏 LeetCode地址 环形链表II 题目 给定一个链表&#xff0c;返回链表开始入环的第一个节点。如果链表无环&#xff0c;则返回null。   为了表示给定链表中的环&#xff0c;我们使用整数pos来表示链表尾连接到链表中的位置&#xff08;索引从0开始&#…