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

【C++】拷贝构造 和 赋值运算符重载

目录:

一、拷贝构造

(一)拷贝函数的特点

二、赋值运算符重载

(一)运算符重载

(二)赋值运算符重载


正文

一、拷贝构造

如果一个构造函数的第一个参数是自身类类型的引用,且任何额外的参数都有默认值,此构造函数也叫做拷贝构造函数,也就是说拷贝构造是一个特殊的构造函数。

(一)拷贝函数的特点

(1)拷⻉构造函数是构造函数的⼀个重载(函数名相同,参数类型/个数不同即可构成重载)

在理解构造函数的前提下,拷贝构造的写法和构造函数的区别在于参数类型的不同(看不懂拷贝构造参数的类型没事,下面会讲)根据定义:函数名相同,参数类型/个数不同即可构成重载。

(2)拷⻉构造函数的参数只有⼀个必须是类类型对象的引⽤,使⽤传值⽅式编译器直接报错,因为语法逻辑上会引发⽆穷递归调⽤。(不理解参数为什么这样写没关系,下面会解释先记住样)

对于传参有三种方式:传值、传址、传引用。一般有传引用就不用传址了,因为更优。

不能用传值是因为形参是实参的一份临时拷贝,函数结束就销毁不影响实参,拷贝构造函数要实实在在的进行两个对象值的拷贝就不能引用传值。

(3)C++规定自定义类型对象进行拷贝行为必须调用拷贝构造,所以这⾥⾃定义类型传值传参和传值返回都会调⽤拷⻉构造完成。

传值返回会调是因为:返回值并不是我们所看到的返回某个变量类型而已,真实操作系统会把返回值先放在寄存器里,函数结束释放空间后将寄存器里的值再传回来。这个过程需要拷贝值到寄存器。

(4)若未显式定义拷⻉构造,编译器会⽣成⾃动⽣成拷⻉构造函数。⾃动⽣成的拷⻉构造对内置类型成员变量会完成值拷⻉/浅拷⻉(⼀个字节⼀个字节的拷⻉),对⾃定义类型成员变量会调⽤他的拷⻉构造。

(5)像Date这样的类成员变量全是内置类型且没有指向什么资源,编译器⾃动⽣成的拷⻉构造就可以完成需要的拷⻉,所以不需要我们显⽰实现拷⻉构造。这⾥还有⼀个⼩技巧,如果⼀个类显⽰实现了析构并释放资源,那么他就 需要显⽰写拷⻉构造,否则就不需要。什么时候需要自己写拷贝构造,就是当你内置类型或自定义类型有指向资源时一定要自己写拷贝构造(资源:动态内存开辟的空间、打开的文件、栈、堆....)

(6)传值引⽤返回,返回的是返回对象的别名(引⽤),没有产⽣拷⻉。但是如果返回对象是⼀个当前函数局部域的局部对象,函数结束就销毁了,那么使⽤引⽤返回是有问题的,这时的引⽤相当于⼀个野引⽤,类似⼀个野指针⼀样。传引⽤返回可以减少拷⻉,但是⼀定要确保返回对象,在当前函数结束后还在,才能⽤引⽤返回。

用一个对象拷贝构造出另一个对象时为什么用引用?

要证明这个问题得从不用引用会如何说起

(如下图)如果不用引用,那么调用拷贝构造函数前将d1的值传给形参d是值传递,系统规定传值调用和传值返回会自动调用拷贝构造,也就是当你把d1传给d时得先把d1中的值通过拷贝构造拷贝给d(把d创造出来)有了d再调用拷贝构造函数Date( Date& d)

而当你每次要调用拷贝构造就要先传值,传值中途又会调用拷贝构造将d1值拷贝给d,一直循环反复就构成死循环(看下图)一直回不到你最初要调用的拷贝构造函数。引用就不一样了,引用不会额外开辟空间图中d是d1的别名,修改d等于直接修改d1同时还避免了值传递在中途调用拷贝构造函数!

(此图是传值调用,用来证明为什么需要引用调用)

特别提醒:类的每个成员函数的第一个参数是this指针,不能显示写但是可以显示调用。调用拷贝构造实际是将d2传给了this指针,d1传给了d。所以函数体内就是把d1的值拷贝构造出d2,可写成this-> d._year =  year 或 _year = d._ year。

因此拷贝构造函数的参数有两个,只是this没显示写;拷贝构造是用一个已存在的对象构造出另一个对象!!

为什么加const?

正规的写法在参数前面会加const。没加不影响当为什么要加?

其实只要涉及引用就最好加加一下,因为(1)引用可以改变指向对象的值,怕被误改(2)权限问题,防止实参本身是const变量,若是不加权限放大报错,加const可以权限缩小和平移但不能权限放大。

我们要是不写拷贝构造,编译器生成的行为是什么?

对于内置类型进行值拷贝/浅拷贝,自定义类型调用它自己的拷贝构造。涉及深浅拷贝

浅拷贝就是对应一个字节一个字节的拷贝过去,深拷贝是当你这个变量有指向一块空间时,像动态开辟的、数组等,要先一模一样开辟一块空间出来,再把里面数据拷贝过来叫深拷贝。

二、赋值运算符重载

(一)运算符重载

两个数之间的运算有+-*/%……,两个类类型要进行运算就不能用普通的运算符了,C++语⾔允许我们通过运算符重载的形式指定新的运算含义。

运算符重载用法:

(1)运算符重载是由operator和后⾯要定义的运算符共同构成。它的返回值由两个类类型的对象运算后结果的类型决定,例如两个类类型中成员判断是否相等返回是布尔值,返回类型为bool;两个类类型中成员相减/加结果为一个整数返回类型为int;

只要涉及传参就会自动调用拷贝构造,所以这里用引用,用了引用最好加上const,防止误改和权限问题报错(参考上面用一个对象拷贝构造出另一个对象时为什么用引用的讲解

(2)重载运算符函数的参数个数和该运算符作⽤的运算对象数量⼀样多。⼀元运算符(单目运算符)有⼀个参数(操作数),⼆元运算符(双目运算符)有两个参数(操作数)

(3)如果⼀个重载运算符函数是成员函数,则它的第⼀个运算对象默认传给隐式的this指针,因此运算符重载作为成员函数时,参数⽐运算对象少⼀个。

(4)运算符重载以后,其优先级和结合性不变。

(5).*  ::  sizeof  ?:  . 注意以上5个运算符不能重载。重载操作符⾄少有⼀个类类型参数,不能通过运算符重载改变内置类型对象的含义,如: int operator+(int x, int y)

调用类成员函数需要用到.*操作符

(6)重载++运算符时,有前置++和后置++,运算符重载函数名都是operator++,⽆法很好的区分。C++规定,后置++重载时,增加⼀个int形参,跟前置++构成函数重载,⽅便区分。只要是个整型就行。

(二)赋值运算符重载

赋值运算符重载是⼀个默认成员函数(就是把运算符重载放到类的public下生成),⽤于完成两个已经存在的对象直接的拷⻉赋值,这⾥要注意跟拷⻉构造区分,拷⻉构造⽤于⼀个对象拷⻉初始化给另⼀个要创建的对象。

赋值运算符重载的特点:

(1)赋值运算符重载是⼀个运算符重载,规定必须重载为成员函数(在类中)。赋值运算重载的参数建议写成const 当前类类型引⽤,否则会传值传参会有拷⻉。 

例如下图:日期类中已经存在的d1、d3对象,将d3赋值给d1调用赋值重载。d1传给隐式的this指针,d3传给d,两个对象赋值之后返回的是d1对象所以返回值为Date类,d1存在this中。为了避免自己给自己赋值导致不必要的问题,在交换前先判断地址是否是同一个对象。

(2)有返回值,且建议写成当前类类型引⽤,引⽤返回可以提⾼效率,有返回值⽬的是为了⽀持连续赋值场景。

(3)赋值重载没有显式实现时,编译器会自动⽣成⼀个默认赋值运算符重载,默认赋值运算符重载⾏为跟默认构造函数类似,对内置类型成员变量会完成值拷贝/浅拷贝(⼀个字节⼀个字节的拷贝),对自定义类型成员变量会调用他的拷贝构造。

因为内置类型是语言自己定义的类型,存的值比较简单,可直接转成指令进行操作不用赋值运算符重载。如果⼀个类显示实现了析构并释放资源,那么他就需要显示写赋值运算符重载,否则就不需要。

赋值重载的深度拷贝是将d1原本资源空间先free掉,再开辟一块和d3一样大的空间给d1,然后再把d3里面的值拷贝过去。所以要判断是否是自己给自己赋值,不然把自己free了还给自己赋值是个大坑!!

小提示:

对以上全部内容大家多理解几遍一定能学会,要相信自己的学习能力。


相关文章:

【C++】拷贝构造 和 赋值运算符重载

目录: 一、拷贝构造 (一)拷贝函数的特点 二、赋值运算符重载 (一)运算符重载 (二)赋值运算符重载 正文 一、拷贝构造 如果一个构造函数的第一个参数是自身类类型的引用,且任何…...

21.UE5游戏存档,读档,函数库

2-23 游戏存档、读档、函数库_哔哩哔哩_bilibili 目录 1.存档蓝图 2.函数库 2.1保存存档 2.2读取存档: 3.加载游戏,保存游戏 3.1游戏实例对象 3.2 加载游戏 3.3保存游戏 这一节的内容较为错综复杂,中间没有运行程序进行阶段性成果的验…...

「Mac玩转仓颉内测版14」PTA刷题篇5 - L1-005 考试座位号

本篇将继续讲解PTA平台上的题目 L1-005 考试座位号,通过考生准考证号与座位号的对应关系,掌握简单的数据查询与映射操作,进一步提升Cangjie编程语言的实际应用能力。 关键词 PTA刷题数据查询映射操作输入输出Cangjie语言 一、L1-005 考试座位…...

Vue3引用高德地图,进行位置标记获取标记信息

首先安装地图插件 cnpm i amap/amap-jsapi-loader --save封装地图子组件 <template><el-dialogtitle"选择地点"width"740px"class"select-map-dialog"v-model"dialogShow":close-on-click-modal"false":modal-or…...

《C++设计模式:重塑游戏角色系统类结构的秘籍》

在游戏开发领域&#xff0c;游戏角色系统的类结构设计至关重要。一个良好的类结构可以使游戏更易于扩展、维护和优化&#xff0c;而 C中的设计模式为我们提供了强大的工具来实现这一目标。 一、理解游戏角色系统的复杂性 游戏角色系统通常具有高度的复杂性。每个角色都有自己…...

深入浅出 Go 语言:现代编程的高效选择

深入浅出 Go 语言:现代编程的高效选择 引言 Go 语言(也称 Golang)是由 Google 开发的一种现代编程语言,面向高效、简单和并发。自 2009 年问世以来,它已迅速成长为许多企业和开发者首选的语言,尤其是在后端开发、云计算和微服务领域。 本文旨在从 Go 语言的设计哲学、…...

RDIFramework.NET CS敏捷开发框架 V6.1发布(.NET6+、Framework双引擎、全网唯一)

RDIFramework.NET C/S敏捷开发框架V6.1版本迎来重大更新与调整&#xff0c;全面重新设计业务逻辑代码&#xff0c;代码量减少一半以上&#xff0c;开发更加高效。全系统引入全新字体图标&#xff0c;整个界面焕然一新。底层引入最易上手的ORM框架SqlSugar&#xff0c;让开发更加…...

vue路由的钩子函数?

在 Vue 中&#xff0c;路由的钩子函数可以用来在导航过程中执行一些操作&#xff0c;比如进行权限验证、页面加载前后的处理等。常用的路由钩子函数包括全局前置守卫、全局解析守卫、全局后置钩子以及路由独享守卫。下面是这些路由守卫函数的简要说明&#xff1a; 全局前置守卫…...

【Java】枚举类映射

在数据库中常用数字来代替字符串类型&#xff0c;编写一个枚举映射类 当数据库的介质类型要存储数字&#xff0c;前端可以任意传参&#xff0c;通过枚举转换后端都会转成数字对应类型 import lombok.Getter;/*** <p>* 存档介质类型* </p>** author Jyang* date 2…...

精华帖分享|浅谈金融时间序列分析与股价随机游走

本文来源于量化小论坛公共讨论区板块精华帖&#xff0c;作者为正扬&#xff0c;发布于2024年6月3日。 以下为精华帖正文&#xff1a; 01 引 时间序列分析是个很唬人的术语&#xff0c;实际上它也不是一个很容易接近的话题。我本科曾经短暂地学过一点点&#xff0c;又看到互联…...

任意文件下载漏洞

1.漏洞简介 任意文件下载漏洞是指攻击者能够通过操控请求参数&#xff0c;下载服务器上未经授权的文件。 攻击者可以利用该漏洞访问敏感文件&#xff0c;如配置文件、日志文件等&#xff0c;甚至可以下载包含恶意代码的文件。 这里再导入一个基础&#xff1a; 你要在网站下…...

LeetCode 445.两数相加 II

题目&#xff1a; 给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。 思路&#xff1a;反转链表 两数相加 I 代码&…...

CentOS 7中查找已安装JDK路径的方法

使用yum安装了jdk8&#xff0c;但是其他中间件需要配置路径的时候&#xff0c;却没办法找到&#xff0c;如何获取jdk路径&#xff1a; 一、确认服务器是否存在jdk java -version 二、查找jdk的 java 命令在哪里 which java 三、找到软链指向的地址 ls -lrt /usr/bin/java l…...

springboot基于Web足球青训俱乐部管理后台系统开发(代码+数据库+LW)

摘 要 随着社会经济的快速发展&#xff0c;人们对足球俱乐部的需求日益增加&#xff0c;加快了足球健身俱乐部的发展&#xff0c;足球俱乐部管理工作日益繁忙&#xff0c;传统的管理方式已经无法满足足球俱乐部管理需求&#xff0c;因此&#xff0c;为了提高足球俱乐部管理效率…...

RHCE的学习(21)

第三章 Shell条件测试 用途 为了能够正确处理Shell程序运行过程中遇到的各种情况&#xff0c;Linux Shell提供了一组测试运算符。 通过这些运算符&#xff0c;Shell程序能够判断某种或者几个条件是否成立。 条件测试在各种流程控制语句&#xff0c;例如判断语句和循环语句中…...

Ubuntu 18.04 配置sources.list源文件(无法安全地用该源进行更新,所以默认禁用该源)

如果你 sudo apt update 时出现诸如 无法安全地用该源进行更新&#xff0c;所以默认禁用该源 的错误&#xff0c;那就换换源吧&#xff0c;链接&#xff1a; https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/ 注意版本&#xff1a; 修改源文件&#xff1a; sudo nano /etc…...

19.UE5道具掉落

2-21 道具掉落&#xff0c;回血、回蓝、升级提升伤害_哔哩哔哩_bilibili 目录 1.道具的创建&#xff0c;道具功能的实现 2.随机掉落 1.道具的创建&#xff0c;道具功能的实现 新建Actor蓝图&#xff0c;并命名为道具总类&#xff0c;添加一个Niagara粒子组件和一个碰撞箱bo…...

MySQL —— MySQL逻辑架构与查询过程

文章目录 MySQL逻辑架构整体分为三层连接层服务层查询缓存解析器优化器执行器 存储引擎层系统文件层 MySQL 查询过程查询过程框图 博客1 博客2 MySQL逻辑架构整体分为三层 最上层为客户端层&#xff0c;并非MySQL所独有&#xff0c;诸如&#xff1a;连接管理、授权认证、权限校…...

ODOO学习笔记(12):自定义模块开发

一、Odoo模块结构基础 基本目录结构 Odoo自定义模块通常有一个特定的目录结构。一个典型的模块目录包含以下文件和文件夹&#xff1a; __init__.py&#xff1a;这是一个Python模块初始化文件。它使得该目录被视为一个Python模块。在这个文件中&#xff0c;你可以通过from. impo…...

Excel单元格中自适应填充多图

实例需求&#xff1a;在Excel插入图片时&#xff0c;由于图片尺寸各不相同&#xff0c;如果希望多个图片填充指定单元格&#xff0c;依靠用户手工调整&#xff0c;不仅费时费力&#xff0c;而且很难实现完全填充。如下图中的产品图册&#xff0c;有三个图片&#xff0c;如下图所…...

20.useMediaQuery

React useMediaQuery 钩子:如何优雅地实现响应式设计? 在现代 Web 开发中,响应式设计是一个关键概念,它允许应用根据不同的屏幕尺寸和设备特性调整其布局和行为。useMediaQuery 钩子提供了一种声明式的方法来在 React 组件中使用媒体查询,使得响应式逻辑的实现变得简单而…...

无人机场景 - 目标检测数据集 - 车辆检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;无人机场景车辆检测数据集&#xff0c;真实场景高质量图片数据&#xff0c;涉及场景丰富&#xff0c;比如无人机场景城市道路行驶车辆图片、无人机场景城市道边停车车辆图片、无人机场景停车场车辆图片、无人机场景小区车辆图片、无人机场景车辆遮挡、车…...

聚合查询(查询)

count:统计表中所有的行数 指定某一列不统计NULL sum:求和 NULL值不参与计算&#xff08;省略&#xff09; avg()&#xff1a;对所有行的指定列求平均值 max&#xff08;&#xff09; min()&#xff1a;求所有指定行中最大值与最小值 分组查询 group by: ROUDN()小数点 havin…...

QT QLineEdit失去焦点事件问题与解决

本文介绍如何获得QLineEdit的失去焦点事件和获得焦点的输入框也会触发失去焦点事件的问题&#xff01; 目录 一、QLineEdit获得失去焦点事件 1.自定义类继承自QLineEdit 2.重写 focusOutEvent 3.使用 二、失去焦点事件问题 1.问题描述 2.问题解决 三、源码分享 lineed…...

Remora

Remora Remora 模型能够独立于碱基识别过程预测甲基化/修饰碱基的状态。Remora 仓库专注于准备修饰碱基训练数据和训练修饰碱基模型。此外,还提供了一些用于运行 Remora 模型和调查原始信号的功能。对于生产环境中的修饰碱基识别,建议使用 Dorado <https://github.com/na…...

MySQL中将一个字符串字段按层级树状展开

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 需求1.分析2.实现3.思路刨析表结构和数据 需求 数据库中有个字段如下 如何将其转换为如下形式&#xff1a; 1.分析 1.他的层级个数是不确定的&#xff0c;也就是说有的有2层有的有5…...

vue面试题8|[2024-11-14]

问题1&#xff1a;什么是渐进式框架? vue.js router vuex element ...插件 vue.js 渐0 router 渐1 vuex 渐2 vue.js只是一个核心库&#xff0c;比如我再添加一个router或者vuex&#xff0c;不断让项目壮大&#xff0c;就是渐进式框…...

ARM(安谋) China处理器

0 Preface/Foreword 0.1 参考博客 Cortex-M23/M33与STAR-MC1星辰处理器 ARM China&#xff0c;2018年4月established&#xff0c;独立运行。 1 处理器类型 1.1 周易AIPU 1.2 STAR-MC1&#xff08;星辰处理器&#xff09; STAT-MC1&#xff0c;主要为满足AIOT应用性能、功…...

基于python Django的boss直聘数据采集与分析预测系统,爬虫可以在线采集,实时动态显示爬取数据,预测基于技能匹配的预测模型

本系统是基于Python Django框架构建的“Boss直聘”数据采集与分析预测系统&#xff0c;旨在通过技能匹配的方式对招聘信息进行分析与预测&#xff0c;帮助求职者根据自身技能找到最合适的职位&#xff0c;同时为招聘方提供更精准的候选人推荐。系统的核心预测模型基于职位需求技…...

MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk)

MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk) 1.计算模型介绍 使用GARCH&#xff08;广义自回归条件异方差&#xff09;模型计算VaR&#xff08;风险价值&#xff09;时&#xff0c;方差法是一个常用的方法。GARCH模型能够捕捉到金融时间序列数据中的波…...

有哪些做策划的用的网站/seo网站推广方式

HTTP协议的下层使用的是tcp。所以我们建立一个tcp连接就能发送接收http请求。dawn底层使用了nio。可是经过dawn的封装之后&#xff0c;我们在编写代码的时候&#xff0c;就和使用普通的堵塞式socket一样 &#xff0c;不须要关注nio的api。能够把我们的精力放在业务逻辑的处理上…...

免费网站最新域名/百度快速排名软件下载

游戏制作软件中最著名的两个游戏引擎是 Unity 和 Unreal Engine。从独立游戏到大型工作室&#xff0c;许多游戏开发商都在使用它们。如果你打算从事游戏行业工作&#xff0c;你肯定曾经问过自己“我的游戏应该使用 Unity 还是 Unreal Engine&#xff1f;” ” 让我们来了解和比…...

南宁3及分销网站制作/站长工具seo综合查询工具

来源&#xff1a;http://www.fhadmin.org/webnewsdetail10.html此项目为Springboot工作流版本 windows 风格,浏览器访问操作使用&#xff0c;非桌面应用程序。1.代码生成器&#xff1a; [正反双向](单表、主表、明细表、树形表&#xff0c;快速开发利器)快速表单构建器 freemak…...

有哪些网站可以做店面设计/seo技术分享

1、 git init 2、把文件添加到本地版本库中&#xff0c; git add . 3、把文件提交到仓库 git commit -m first commit’ 4、关联到远程库 git remote add origin 你的远程库地址 5、远程库与本地同步合并 git pull --rebase origin master 6、推送到远程仓库&#xf…...

建设通类似网站/月入百万的游戏代理

Code /* 队列基本操作 InitQueue(&Q)&#xff1a;初始化队列&#xff0c;构造一个空队列Q。 QueueEmpty(Q)&#xff1a;判队列空&#xff0c;若队列Q为空返回true&#xff0c;否则返回false。 EnQueue(&Q, x)&#xff1a;入队&#xff0c;若队列Q未满&#xff0c;则将…...

用java做网站步骤/哪里有网络推广

环境&#xff1a;用yum -y install sendmail* mail* 简易安装sendmail后&#xff0c;未做任何配置问题&#xff1a;mail -s 发不了邮件命令&#xff1a; mail -s "ssssss" xxxx163.com < body.txt 其中 "ssssss" 是邮件标题&#xff0c;body.txt里是文…...