当前位置: 首页 > news >正文

拷贝构造、移动构造、拷贝赋值、移动赋值

        最近在学习C++的拷贝构造函数时发现一个问题:在函数中返回局部的类对象时,并没有调用拷贝构造函数。针对这个问题,查阅了一些资料,这里记录整理一下。

调用拷贝构造函数的三种情况:

① 用一个类去初始化另一个对象时(初始化的为新对象)

②一个对象作为参数,以值传递的方式传入函数内

③ 返回值作为类对象,函数执行完成返回调用时。

下面写了一个示例代码:

#include <iostream>
#include <string>
using namespace std;
class Demo {
public:Demo(string name, int data) : m_name(name), m_data(data) {cout << "默认构造函数" << endl;}Demo(const Demo& other) {cout << "拷贝构造函数" << endl;m_name = other.m_name;m_data = other.m_data;}Demo& operator=(const Demo& other) {cout << "拷贝赋值运算符重载" << endl;m_name = other.m_name;m_data = other.m_data;return *this; //return *this 是为了可以连续赋值}Demo(const Demo&& other) {cout << "移动构造函数" <<  endl;m_name = other.m_name;m_data = other.m_data;}Demo& operator=(const Demo&& other) {cout << "移动赋值运算符重载" << endl;m_name = other.m_name;m_data = other.m_data;return *this;}
private:string m_name;int m_data;
};void test01()
{//默认构造Demo a("zhangsam", 10);Demo b("lisi", 20);//拷贝构造:使用一个类去初始化另一个对象时Demo c = a;//拷贝赋值运算符重载:使用一个类对另一个对象赋值c = b = a;//移动构造。使用右值对象对初始化一个对象时Demo e = move(a);//移动赋值运算符重载:使用一个右值对象对另一个对象赋值e = move(b);
}//当类对象做形参是,调用拷贝构造函数
Demo test02(Demo d1)
{Demo f("wangwu", 30);//返回一个类对象时,这里调用了移动构造函数//这里编译器默认优化,需要增加-fno-elide-constructor编译选项,但是调用的确实移动构造函数//原因是,在新的标砖中,当编译器识别到返回的是一个局部的对象,将自动使用move转化。//前提是类中自定义了移动构造函数,否则将调用拷贝构造函数return f;
}
int main()
{test01();cout << "-----------" << endl;Demo a1("test", 40);test02(a1);cout << "-----------" << endl;return 0;
}

最开始正常编译 g++ test.cpp  

执行结果:

        可以看到,test02函数最后返回一个f对象,但是并没有调用拷贝构造函数。

① Demo a1("test", 40);  //默认构造函数

② a1形参传参 //拷贝构造函数

③ 函数内  Demo f("wangwu", 30); //默认构造函数

④ return f //???未打印任何东西

        查阅资料后,说是需要增加一个编译选项 -fno-elide-constructors, 果然增加后,出现了相应的打印。

但是,,为什么是调用的移动构造函数。。。

 再次查阅资料到:当从同类型的右值(亡值(将亡值))或纯右值)(C++17前)亡值初始化(直接初始化或者复制初始化)对象时会调用移动构造函数,情况包括:

1、初始化 T a = std::move(b) 或 T a(std::move(b))

2、函数实参传递  f(std::move(a)) 其中a的类型是T 且f 是Ret f (T t);

3、函数返回:在像T f() 这样的函数中的retuen a;,其中a的类型是T, 且T中自定义了移动构造函数。

        所以,,,函数中的局部类对象其实是一个将亡值??

        然后又百度了下将亡值的概念和定义:

        就传统的理解而言,函数foo的返回值在内部创建然后被赋值给v(外部接收返回值的对象),然后v获得这个对象时,会将整个temp拷贝一份,然后把temp销毁。如果这个temp非常大,这将造成大量额外的开销(这也是c++一直被诟病的问题)。在新的特性里面,会自动检测这个值是不死局部的,是的话,就直接move()了。用不同的编译器,不同的开关(debug,relese)结果可能都不一样。

        例如,一个函数v = foo(),接收返回值的v是一个左值,foo()返回的值也就是一个右值(也是纯右值)。但是v可以被别的变量捕获到,而foo()产生的那个返回值作为一个临时变量,一旦被v赋值后,将立即被销毁,无法获取,也不能修改。

相关文章:

拷贝构造、移动构造、拷贝赋值、移动赋值

最近在学习C的拷贝构造函数时发现一个问题&#xff1a;在函数中返回局部的类对象时&#xff0c;并没有调用拷贝构造函数。针对这个问题&#xff0c;查阅了一些资料&#xff0c;这里记录整理一下。 调用拷贝构造函数的三种情况&#xff1a; ① 用一个类去初始化另一个对象时&a…...

Python3 笔记:math模块

要使用 math 函数必须先导入math模块 语法&#xff1a;import math Python math 模块提供了许多对浮点数的数学运算函数。 math 模块下的函数&#xff0c;返回值均为浮点数&#xff0c;除非另有明确说明。 如果需要计算复数&#xff0c;需使用 cmath 模块中的同名函数。 m…...

python -【四】函数

函数 一、函数的基础 函数&#xff1a;是组织好的&#xff0c;可以重复使用的&#xff0c;用来实现特定功能的代码段 语法 def 函数名(入参): return 出参 # 定义函数 def out_hello():print(hello ~~~)# 调用/使用/执行函数 out_hello()练习题 自定义一个函数&#xff0c…...

力扣 5. 最长回文子串 python AC

动态规划 class Solution:def longestPalindrome(self, s):size len(s)maxl 1start 0dp [[False] * size for _ in range(size)]for i in range(size):dp[i][i] Truefor L in range(2, size 1):for i in range(size):j L i - 1if j > size:breakif s[i] s[j]:if L…...

【微机原理及接口技术】可编程计数器/定时器8253

【微机原理及接口技术】可编程计数器/定时器8253 文章目录 【微机原理及接口技术】可编程计数器/定时器8253前言一、8253的内部结构和引脚二、8253的工作方式三、8253的编程总结 前言 本篇文章就8253芯片展开&#xff0c;详细介绍8253的内部结构和引脚&#xff0c;8253的工作方…...

23种设计模式之一— — — —装饰模式详细介绍与讲解

装饰模式详细讲解 一、定义二、装饰模式结构核心思想模式角色模式的UML类图应用场景模式优点模式缺点 实例演示图示代码演示运行结果 一、定义 装饰模式&#xff08;别名&#xff1a;包装器&#xff09; 装饰模式&#xff08;Decorator Pattern&#xff09;是结构型的设计模式…...

2024年2月28日 星期三

2024年2月28日 星期三 农历正月十九 1. 住建部&#xff1a;各城市要做好今明两年住房发展计划&#xff0c;防止市场大起大落。 2. 政协委员赵长龙建议&#xff1a;增加元旦、端午、中秋高速免费&#xff0c;周六日半价。 3. 人民法院案例库开始对社会开放&#xff0c;与中国…...

Java中的super关键字详解

在Java编程中&#xff0c;super关键字是一个非常重要的概念&#xff0c;尤其是在继承和多态的场景中。理解super关键字的使用方法和其背后的机制&#xff0c;对于掌握面向对象编程&#xff08;OOP&#xff09;的基本概念至关重要。本篇博客将详细讲解super关键字的各种用法及其…...

消消乐游戏开发,三消游戏,消除小游戏

消消乐是一款非常受欢迎的休闲消除类游戏&#xff0c;通常也被称为“三消游戏”。这类游戏的主要目标是通过交换和匹配三个或更多相同的物品来清除它们&#xff0c;从而得分并通过关卡。以下是一些消消乐游戏的基本特点和玩法&#xff1a; 基本玩法 交换和匹配&#xff1a;玩…...

三十三、openlayers官网示例Drawing Features Style——在地图上绘制图形,并修改绘制过程中的颜色

这篇讲的是使用Draw绘制图形时根据绘制形状设置不同颜色。 根据下拉框中的值在styles对象中取对应的颜色对象&#xff0c;new Draw的时候将其设置为style参数。 const styles {Point: {"circle-radius": 5,"circle-fill-color": "red",},LineS…...

Vue——事件修饰符

文章目录 前言阻止默认事件 prevent阻止事件冒泡 stop 前言 在官方文档中对于事件修饰符有一个很好的说明&#xff0c;本篇文章主要记录验证测试的案例。 官方文档 事件修饰符 阻止默认事件 prevent 在js原生的语言中&#xff0c;可以根据标签本身的事件对象进行阻止默认事件…...

Go语言GoFly框架快速新增接口/上手写代码

拿到一个新框架大家可能无从下手&#xff0c;因为你对框架设计思路、结构不了解&#xff0c;从而产生恐惧&#xff0c;所以我们框架是通过简单可视化界面安装&#xff0c;安装后即可看到效果&#xff0c;然后点击先点点看各个功能&#xff0c;看现有的功能是怎么写的&#xff0…...

【Vue】v-else 和 v-else-if

作用&#xff1a;辅助v-if进行判断渲染 语法&#xff1a; v-else v-else-if"表达式"PS&#xff1a;需要紧接着v-if使用 示例代码&#xff1a; <body><div id"app"><p v-if"gender 1">性别&#xff1a;♂ 男</p><…...

一致性hash算法原理图和负载均衡原理-urlhash与least_conn案例

一. 一致性hash算法原理图 4台服务器计算hash值图解 减少一台服务3台服务器计算hash值图解 增加一台服务器5台服务器计算hash值图解 二. 负载均衡原理-urlhash与least_conn 2.1.urlhash案例 # urlhash upstream tomcats {hash $requ...

MySQL建库

删除数据库 新建数据库 右键-新建数据库 字符集选中utf8(支持中文) 修改字符集 右键--数据库的属性 将字符集支持的数量变少可以修改...

系统资源监控器工具glances的使用详解

目录 1、glances工具介绍 2、安装方式 3、glances的工具界面说明 4、常用的参数选项 5、常用快捷键说明 1、glances工具介绍 glances可以分析系统的 CPU使用率、内存使用率、内核统计信息和运行队列信息磁盘I/O速度、传输和读/写比率、磁盘适配器网络I/O速度、传输和读/写…...

JDBC使用QreryRunner简化SQL查询注意事项

QreryRunner是Dbutils的核心类之一&#xff0c;它显著的简化了SQL查询&#xff0c;并与ResultSetHandler协同工作将使编码量大为减少。 注意事项 1. 使用QreryRunner必须保证实体类的变量名&#xff0c;和sql语句中要查找的字段名必须相同&#xff0c;否则查询 不到数据,会出…...

前缀和(下)

目录 热身&#xff1a; 寻找数组的中心下标 题解&#xff1a; 代码&#xff1a; 进阶&#xff1a; 除自身之外数组的乘积 题解&#xff1a; 代码&#xff1a; 和为K的子数组 题解&#xff1a; 代码&#xff1a; 和可被 K 整除的子数组 题解&#xff1a; 同余定理…...

【排序算法】希尔排序

前言&#xff1a;学习希尔排序前最好先掌握插入排序&#xff0c;在进行&#xff1b;不会的可以点击——>【排序算法】插入排序-CSDN博客 一、希尔排序&#xff1a; 希尔排序&#xff0c;也称为缩小增量排序&#xff0c;是一种基于插入排序的快速改进算法。由Donald Shell于1…...

数学建模--LaTex插入表格详细介绍

目录 1.插入普通的边线表格 3.三线表的插入和空格说明 3.基于复杂情况下表格的插入 1.插入普通的边线表格 &#xff08;1&#xff09;像这个右边的生成的这个比较普通的表格&#xff0c;我们是使用下面的代码实现的&#xff1a; &#xff08;2&#xff09;和插入一个一个图片…...

未来已来:Flutter引领的安卓与跨平台开发奇幻之旅

引言 随着移动开发技术的飞速发展&#xff0c;跨平台开发框架如Flutter正逐渐改变着传统的安卓和iOS开发格局。作为一名资深的安卓开发工程师&#xff0c;我深刻感受到了Flutter带来的变革和机遇。今天&#xff0c;我想与大家分享Flutter在跨平台开发中的奇幻之旅&#xff0c;…...

如何将Windows PC变成Wi-Fi热点?这里提供详细步骤

序言 Windows 10和Windows 11都有内置功能,可以将你的笔记本电脑(或台式机)变成无线热点,允许其他设备连接到它并共享你的互联网连接。以下是操作指南。 由于Windows中隐藏的虚拟Wi-Fi适配器功能,你甚至可以在连接到另一个Wi-Fi网络或无线路由器时创建Wi-Fi热点,通过另…...

报错:Cannot invoke “springfox.documentation.service.ParameterType.getIn()“

文章目录 前言一、报错分析二、解决办法修改代码 总结 前言 遇到报错&#xff1a;Cannot invoke "springfox.documentation.service.ParameterType.getIn()" because the return value of "springfox.documentation.service.RequestParameter.getIn()" is …...

一个生动的例子——通过ERC20接口访问Tether合约

生动的例子 USDT&#xff1a;符合ERC20标准的美元稳定币&#xff0c;Tether合约获得测试网上Tether合约地址通过自己写的ERC20接口访问这个合约 Tether合约地址&#xff1a;0xdAC17F958D2ee523a2206206994597C13D831ec7 IERC20.sol // SPDX-License-Identifier: GPL-3.0pra…...

新媒体时代,LCD电子价签赋予零售场景新活力

近年来&#xff0c;全球企业迅速掀起了数字化转型的浪潮&#xff0c;加速了新零售科技的发展与应用。在实体零售门店中&#xff0c;商品货架显示逐渐趋向智能化和多样化。然而&#xff0c;在信息传播日益碎片化和视频化的时代&#xff0c;零售门店如何更有效地吸引消费者的注意…...

芋道源码 / yudao-cloud:前端技术架构探索与实践

摘要&#xff1a; 随着企业信息化建设的深入&#xff0c;后台管理系统在企业运营中扮演着至关重要的角色。本文将以芋道源码的yudao-cloud项目为例&#xff0c;深入探讨其前端技术架构的设计思路、关键技术与实现细节&#xff0c;并分享在开发过程中遇到的挑战与解决方案。 一、…...

2024 angstromCTF re 部分wp

Guess the Flag 附件拖入ida 比较简单&#xff0c;就一个异或 switcher 附件拖入ida 明文flag Polyomino 附件拖入ida 需要输入九个数&#xff0c;然后进入处理和判断&#xff0c;如果满足条件则进入输出flag部分&#xff0c;flag和输入有关&#xff0c;所以要理解需要满足什么…...

STL库--priority_queue

目录 priority_queue定义 prority_queue容器内元素的访问 priority_queue()常用函数实例解析 priority_queue内元素优先级的设置 priority_queue的常见用途 priority_queue又称为优先队列&#xff0c;其底层是用堆来进行实现的。在优先队列中&#xff0c;队首元素一定是当…...

网络编程 —— Http使用httpClient实现页面爬虫

先去找类型的a标签 取出图片所在网址 取出https://desk.3gbizhi.com/deskMV/438.html 搭建Form界面 Http类 public static HttpClient Client { get; } static Http() {HttpClientHandler handler new HttpClientHandler();//处理消息对象//ServerCertificateCustomValidat…...

【本地运行chatgpt-web】启动前端项目和service服务端项目,也是使用nodejs进行开发的。两个都运行成功才可以使用!

1&#xff0c;启动web界面 https://github.com/Chanzhaoyu/chatgpt-web#node https://nodejs.org/en/download/package-manager # 使用nvm 安装最新的 20 版本。 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source /root/.bashrc n…...