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

相关文章

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

SpringBoot整合jasypt实现重要数据加密

《SpringBoot整合jasypt实现重要数据加密》Jasypt是一个专注于简化Java加密操作的开源工具,:本文主要介绍详细介绍了如何使用jasypt实现重要数据加密,感兴趣的小伙伴可... 目录jasypt简介 jasypt的优点SpringBoot使用jasypt创建mapper接口配置文件加密

Qt把文件夹从A移动到B的实现示例

《Qt把文件夹从A移动到B的实现示例》本文主要介绍了Qt把文件夹从A移动到B的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录如何移动一个文件? 如何移动文件夹(包含里面的全部内容):如何删除文件夹:QT 文件复制,移动(

Golang中拼接字符串的6种方式性能对比

《Golang中拼接字符串的6种方式性能对比》golang的string类型是不可修改的,对于拼接字符串来说,本质上还是创建一个新的对象将数据放进去,主要有6种拼接方式,下面小编就来为大家详细讲讲吧... 目录拼接方式介绍性能对比测试代码测试结果源码分析golang的string类型是不可修改的,对于拼接字

mysql线上查询之前要性能调优的技巧及示例

《mysql线上查询之前要性能调优的技巧及示例》文章介绍了查询优化的几种方法,包括使用索引、避免不必要的列和行、有效的JOIN策略、子查询和派生表的优化、查询提示和优化器提示等,这些方法可以帮助提高数... 目录避免不必要的列和行使用有效的JOIN策略使用子查询和派生表时要小心使用查询提示和优化器提示其他常

Python重命名文件并移动到对应文件夹

《Python重命名文件并移动到对应文件夹》在日常的文件管理和处理过程中,我们可能会遇到需要将文件整理到不同文件夹中的需求,下面我们就来看看如何使用Python实现重命名文件并移动到对应文件夹吧... 目录检查并删除空文件夹1. 基本需求2. 实现代码解析3. 代码解释4. 代码执行结果5. 总结方法补充在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录