移动构造函数是否标记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

相关文章

java中判断json key是否存在的几种方法

《java中判断jsonkey是否存在的几种方法》在使用Java处理JSON数据时,如何判断某一个key是否存在?本文就来介绍三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目http://www.chinasem.cn录第一种方法是使用 jsONObject 的 has 方法

MySQL使用EXISTS检查记录是否存在的详细过程

《MySQL使用EXISTS检查记录是否存在的详细过程》EXISTS是SQL中用于检查子查询是否返回至少一条记录的运算符,它通常用于测试是否存在满足特定条件的记录,从而在主查询中进行相应操作,本文给大... 目录基本语法示例数据库和表结构1. 使用 EXISTS 在 SELECT 语句中2. 使用 EXIS

Docker多阶段镜像构建与缓存利用性能优化实践指南

《Docker多阶段镜像构建与缓存利用性能优化实践指南》这篇文章将从原理层面深入解析Docker多阶段构建与缓存机制,结合实际项目示例,说明如何有效利用构建缓存,组织镜像层次,最大化提升构建速度并减少... 目录一、技术背景与应用场景二、核心原理深入分析三、关键 dockerfile 解读3.1 Docke

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. 深度剖析: