移动构造函数是否标记noexcept对性能有重要影响

2024-05-05 05:36

本文主要是介绍移动构造函数是否标记noexcept对性能有重要影响,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 移动构造标记noexcept时才会被正确调用

#include <iostream>
#include <string>
#include <vector>class Vehicle{
public:Vehicle(){std::cout << "Vehicle default-ctor called.\n";}Vehicle(const std::string& brand) : brand_(brand) {std::cout << "Vehicle ctor called.\n";}virtual ~Vehicle(){std::cout << "Vehicle dtor called.\n";}Vehicle(const Vehicle& rhs) : brand_(rhs.brand_) {std::cout << __PRETTY_FUNCTION__ << std::endl;}Vehicle& operator=(const Vehicle& rhs) &{Vehicle(rhs).swap(*this);std::cout << __PRETTY_FUNCTION__ << std::endl;return *this;}void swap(Vehicle& rhs) noexcept {brand_.swap(rhs.brand_);}Vehicle(Vehicle&& rhs) noexcept: brand_(rhs.brand_) {std::cout << __PRETTY_FUNCTION__ << std::endl;}Vehicle& operator=(Vehicle&& rhs) & noexcept {brand_ = rhs.brand_;std::cout << __PRETTY_FUNCTION__ << std::endl;return *this;}private:std::string brand_;
};Vehicle getVehicle(){return Vehicle("Tesla");
}int main() {// 调用getVehicle()时仅会调用一次构造函数,并没有调用移动赋值运算符,这是因为存在返回值优化// 所以函数可以直接返回对象,不需要通过出参的方式Vehicle vec1 = getVehicle();  // Vehicle ctor called.Vehicle vec2("BYD");          // Vehicle ctor called.std::cout << std::string(40, '-') << std::endl;vec2 = getVehicle();          // Vehicle ctor called.// Vehicle& Vehicle::operator=(Vehicle&&) &// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;Vehicle vec3(std::move(vec1));  // Vehicle::Vehicle(Vehicle&&)std::cout << std::string(40, '-') << std::endl;std::vector<Vehicle> vecs1(4, Vehicle("LINKO"));  // Vehicle ctor called.// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;std::vector<Vehicle> vecs2(4);     // Vehicle default-ctor called.// Vehicle default-ctor called.// Vehicle default-ctor called.// Vehicle default-ctor called.std::cout << std::string(40, '-') << std::endl;vecs2.emplace_back();    // Vehicle default-ctor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;vecs2.emplace_back();   // Vehicle default-ctor called.std::cout << std::string(40, '-') << std::endl;vecs2.push_back(Vehicle());  // Vehicle default-ctor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;
}

输出:

Vehicle ctor called.
Vehicle ctor called.
----------------------------------------
Vehicle ctor called.
Vehicle& Vehicle::operator=(Vehicle&&) &
Vehicle dtor called.
----------------------------------------
Vehicle::Vehicle(Vehicle&&)
----------------------------------------
Vehicle ctor called.
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle dtor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle default-ctor called.
Vehicle default-ctor called.
Vehicle default-ctor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
----------------------------------------
Vehicle default-ctor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
----------------------------------------
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.

2. 当移动构造未标记noexcept时该调用移动构造的时候可能调用的是拷贝构造

#include <iostream>
#include <string>
#include <vector>class Vehicle{
public:Vehicle(){std::cout << "Vehicle default-ctor called.\n";}Vehicle(const std::string& brand) : brand_(brand) {std::cout << "Vehicle ctor called.\n";}virtual ~Vehicle(){std::cout << "Vehicle dtor called.\n";}Vehicle(const Vehicle& rhs) : brand_(rhs.brand_) {std::cout << __PRETTY_FUNCTION__ << std::endl;}Vehicle& operator=(const Vehicle& rhs) &{Vehicle(rhs).swap(*this);std::cout << __PRETTY_FUNCTION__ << std::endl;return *this;}void swap(Vehicle& rhs) noexcept {brand_.swap(rhs.brand_);}Vehicle(Vehicle&& rhs) /*noexcept*/: brand_(rhs.brand_) {std::cout << __PRETTY_FUNCTION__ << std::endl;}Vehicle& operator=(Vehicle&& rhs) & noexcept {brand_ = rhs.brand_;std::cout << __PRETTY_FUNCTION__ << std::endl;return *this;}private:std::string brand_;
};Vehicle getVehicle(){return Vehicle("Tesla");
}int main() {// 调用getVehicle()时仅会调用一次构造函数,并没有调用移动赋值运算符,这是因为存在返回值优化// 所以函数可以直接返回对象,不需要通过出参的方式Vehicle vec1 = getVehicle();  // Vehicle ctor called.Vehicle vec2("BYD");          // Vehicle ctor called.std::cout << std::string(40, '-') << std::endl;vec2 = getVehicle();          // Vehicle ctor called.// Vehicle& Vehicle::operator=(Vehicle&&) &// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;Vehicle vec3(std::move(vec1));  // Vehicle::Vehicle(Vehicle&&)std::cout << std::string(40, '-') << std::endl;std::vector<Vehicle> vecs1(4, Vehicle("LINKO"));  // Vehicle ctor called.// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;std::vector<Vehicle> vecs2(4);     // Vehicle default-ctor called.// Vehicle default-ctor called.// Vehicle default-ctor called.// Vehicle default-ctor called.std::cout << std::string(40, '-') << std::endl;vecs2.emplace_back();   // Vehicle default-ctor called.// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle dtor called.// Vehicle dtor called.// Vehicle dtor called.// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;vecs2.emplace_back();   // Vehicle default-ctor called.std::cout << std::string(40, '-') << std::endl;vecs2.push_back(Vehicle());  // Vehicle default-ctor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;
}

输出结果:

Vehicle ctor called.
Vehicle ctor called.
----------------------------------------
Vehicle ctor called.
Vehicle& Vehicle::operator=(Vehicle&&) &
Vehicle dtor called.
----------------------------------------
Vehicle::Vehicle(Vehicle&&)
----------------------------------------
Vehicle ctor called.
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle dtor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle default-ctor called.
Vehicle default-ctor called.
Vehicle default-ctor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
----------------------------------------
Vehicle default-ctor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
----------------------------------------
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.

这篇关于移动构造函数是否标记noexcept对性能有重要影响的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/960899

相关文章

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

sysmain服务可以禁用吗? 电脑sysmain服务关闭后的影响与操作指南

《sysmain服务可以禁用吗?电脑sysmain服务关闭后的影响与操作指南》在Windows系统中,SysMain服务(原名Superfetch)作为一个旨在提升系统性能的关键组件,一直备受用户关... 在使用 Windows 系统时,有时候真有点像在「开盲盒」。全新安装系统后的「默认设置」,往往并不尽编

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet

Java慢查询排查与性能调优完整实战指南

《Java慢查询排查与性能调优完整实战指南》Java调优是一个广泛的话题,它涵盖了代码优化、内存管理、并发处理等多个方面,:本文主要介绍Java慢查询排查与性能调优的相关资料,文中通过代码介绍的非... 目录1. 事故全景:从告警到定位1.1 事故时间线1.2 关键指标异常1.3 排查工具链2. 深度剖析:

深入解析Java NIO在高并发场景下的性能优化实践指南

《深入解析JavaNIO在高并发场景下的性能优化实践指南》随着互联网业务不断演进,对高并发、低延时网络服务的需求日益增长,本文将深入解析JavaNIO在高并发场景下的性能优化方法,希望对大家有所帮助... 目录简介一、技术背景与应用场景二、核心原理深入分析2.1 Selector多路复用2.2 Buffer

基于Python Playwright进行前端性能测试的脚本实现

《基于PythonPlaywright进行前端性能测试的脚本实现》在当今Web应用开发中,性能优化是提升用户体验的关键因素之一,本文将介绍如何使用Playwright构建一个自动化性能测试工具,希望... 目录引言工具概述整体架构核心实现解析1. 浏览器初始化2. 性能数据收集3. 资源分析4. 关键性能指

把Python列表中的元素移动到开头的三种方法

《把Python列表中的元素移动到开头的三种方法》在Python编程中,我们经常需要对列表(list)进行操作,有时,我们希望将列表中的某个元素移动到最前面,使其成为第一项,本文给大家介绍了把Pyth... 目录一、查找删除插入法1. 找到元素的索引2. 移除元素3. 插入到列表开头二、使用列表切片(Lis