拷贝构造、移动构造、拷贝赋值、移动赋值
最近在学习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的拷贝构造函数时发现一个问题:在函数中返回局部的类对象时,并没有调用拷贝构造函数。针对这个问题,查阅了一些资料,这里记录整理一下。 调用拷贝构造函数的三种情况: ① 用一个类去初始化另一个对象时&a…...
Python3 笔记:math模块
要使用 math 函数必须先导入math模块 语法:import math Python math 模块提供了许多对浮点数的数学运算函数。 math 模块下的函数,返回值均为浮点数,除非另有明确说明。 如果需要计算复数,需使用 cmath 模块中的同名函数。 m…...
python -【四】函数
函数 一、函数的基础 函数:是组织好的,可以重复使用的,用来实现特定功能的代码段 语法 def 函数名(入参): return 出参 # 定义函数 def out_hello():print(hello ~~~)# 调用/使用/执行函数 out_hello()练习题 自定义一个函数,…...
力扣 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芯片展开,详细介绍8253的内部结构和引脚,8253的工作方…...
23种设计模式之一— — — —装饰模式详细介绍与讲解
装饰模式详细讲解 一、定义二、装饰模式结构核心思想模式角色模式的UML类图应用场景模式优点模式缺点 实例演示图示代码演示运行结果 一、定义 装饰模式(别名:包装器) 装饰模式(Decorator Pattern)是结构型的设计模式…...
2024年2月28日 星期三
2024年2月28日 星期三 农历正月十九 1. 住建部:各城市要做好今明两年住房发展计划,防止市场大起大落。 2. 政协委员赵长龙建议:增加元旦、端午、中秋高速免费,周六日半价。 3. 人民法院案例库开始对社会开放,与中国…...
Java中的super关键字详解
在Java编程中,super关键字是一个非常重要的概念,尤其是在继承和多态的场景中。理解super关键字的使用方法和其背后的机制,对于掌握面向对象编程(OOP)的基本概念至关重要。本篇博客将详细讲解super关键字的各种用法及其…...
消消乐游戏开发,三消游戏,消除小游戏
消消乐是一款非常受欢迎的休闲消除类游戏,通常也被称为“三消游戏”。这类游戏的主要目标是通过交换和匹配三个或更多相同的物品来清除它们,从而得分并通过关卡。以下是一些消消乐游戏的基本特点和玩法: 基本玩法 交换和匹配:玩…...
三十三、openlayers官网示例Drawing Features Style——在地图上绘制图形,并修改绘制过程中的颜色
这篇讲的是使用Draw绘制图形时根据绘制形状设置不同颜色。 根据下拉框中的值在styles对象中取对应的颜色对象,new Draw的时候将其设置为style参数。 const styles {Point: {"circle-radius": 5,"circle-fill-color": "red",},LineS…...
Vue——事件修饰符
文章目录 前言阻止默认事件 prevent阻止事件冒泡 stop 前言 在官方文档中对于事件修饰符有一个很好的说明,本篇文章主要记录验证测试的案例。 官方文档 事件修饰符 阻止默认事件 prevent 在js原生的语言中,可以根据标签本身的事件对象进行阻止默认事件…...
Go语言GoFly框架快速新增接口/上手写代码
拿到一个新框架大家可能无从下手,因为你对框架设计思路、结构不了解,从而产生恐惧,所以我们框架是通过简单可视化界面安装,安装后即可看到效果,然后点击先点点看各个功能,看现有的功能是怎么写的࿰…...
【Vue】v-else 和 v-else-if
作用:辅助v-if进行判断渲染 语法: v-else v-else-if"表达式"PS:需要紧接着v-if使用 示例代码: <body><div id"app"><p v-if"gender 1">性别:♂ 男</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的核心类之一,它显著的简化了SQL查询,并与ResultSetHandler协同工作将使编码量大为减少。 注意事项 1. 使用QreryRunner必须保证实体类的变量名,和sql语句中要查找的字段名必须相同,否则查询 不到数据,会出…...
前缀和(下)
目录 热身: 寻找数组的中心下标 题解: 代码: 进阶: 除自身之外数组的乘积 题解: 代码: 和为K的子数组 题解: 代码: 和可被 K 整除的子数组 题解: 同余定理…...
【排序算法】希尔排序
前言:学习希尔排序前最好先掌握插入排序,在进行;不会的可以点击——>【排序算法】插入排序-CSDN博客 一、希尔排序: 希尔排序,也称为缩小增量排序,是一种基于插入排序的快速改进算法。由Donald Shell于1…...
数学建模--LaTex插入表格详细介绍
目录 1.插入普通的边线表格 3.三线表的插入和空格说明 3.基于复杂情况下表格的插入 1.插入普通的边线表格 (1)像这个右边的生成的这个比较普通的表格,我们是使用下面的代码实现的: (2)和插入一个一个图片…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
