【C++】类和对象——拷贝构造和赋值运算符重载
上一篇我们讲了构造函数,就是对象实例化时会自动调用,那么,我们这里的拷贝构造在形式上是构造函数的一个重载,拷贝构造其实也是一种构造函数,那么我们就可以引出这里的规则
1.拷贝构造函数的函数名必须与类名相同。
2.拷贝构造函数的参数必须为一个引用(否则会引起无穷递归),通常是 const 类型的引用,用来指定被拷贝的对象。
3.拷贝构造函数用来初始化一个新的对象,新的对象与被拷贝的对象应该属于同一类。
4.如果不手动定义拷贝构造函数,那么编译器会自动生成一个默认的拷贝构造函数,该函数进行浅拷贝。
其实一个日期的类进行浅拷贝就行了,只需要把值给复制过去;但是对于一个栈的话,因为有了自动调用析构函数这个特性,那么我们就不能只去浅拷贝,而是把栈在堆上申请的空间包括值都要去拷贝一份(这里就是指拷贝指针背后的资源),这里也就是我们所说的深拷贝
我们看一下第四条规则,它是会生成一个默认的拷贝构造函数的,对于内置类型是这样的

当然对于自定义类型来说会去调用它的拷贝构造函数
根据第一二条规则我们可以看出拷贝构造函数的基本形式是这样的

当然了,根据第四条,我们其实不写日期类的拷贝构造函数的话编译器是会默认生成的。这个拷贝构造函数其实在栈这一些类中才是有价值的
我们看下面这样一个例子
class stack {
public:stack(int capacity=3) {cout << "stack" << endl;int* tmp = (int*)malloc(sizeof(int) * capacity);if (tmp == nullptr) {perror("malloc failed");return;}_a = tmp;_top = 0;_capacity = capacity;}~stack(){cout << "~stack" << endl;free(_a);_a = nullptr;_top = 0;_capacity = 0;}
private:int* _a;int _top;int _capacity;
};
void func(stack x) {cout << "func" << endl;
}
int main() {stack s1;func(s1);return 0;
}
这个代码其实是会报错的,因为s1传给x时是要调用一次拷贝构造的(因为我们一直说形参是实参的一份临时拷贝),而我们没有写拷贝构造函数,那么此时编译器就会默认进行浅拷贝,也就是把s1的_a指针的值去给了x,当要出x的作用域时,x就会调用它的析构函数,此时就释放了指针指向的空间,函数出来后要出s1的作用域时又要调用析构函数,这就导致一块空间被释放(free)了两回,这时就会报错,这也就解释了为什么开头我说跟析构函数有关
那么写上栈的拷贝构造函数就可以了
stack(const stack& x) {int* tmp = (int*)malloc(sizeof(int) * _capacity);if (tmp == nullptr) {perror("malloc fail");exit(-1);}memcpy(tmp, x._a, sizeof(int) * x._top);_a = tmp;_top = x._top;_capacity = x._capacity;}
下边的赋值运算符重载也是类的默认成员函数中的一个,说这个之前,我们还是先解释一下什么叫运算符重载
我们平常在用运算符时(> + = >= 等),只能对于内置类型进行使用,对于自定义类型不能使用,因为编译器认识内置类型,它知道怎么去运行。但是对于自定义类型它也不知道怎么去操作。
这时呢?为了方便,我们就要去写一个类的函数(这里以==为例),我们写是会写,但是可能写的函数名可能会使别人不认识,这时,我们的C++祖师爷就制定了一个标准,函数名就是operator操作符
比如说,我们写一个日期类的比较相等的函数
bool operator==(const Date&d1,const Date& d2) {if (d1._year == d2._year && d1._month == d2._month && d1._day == d2._day) {return true;}return false;
}
但是有一个问题,就是我们的成员变量一般是私有的,也就是在类外是访问不了的,我们当然访问有很多种方式,但几乎都是用一个类里面的函数把值给弄出来,那我们还不如直接把运算符重载的函数放到类中,把它变成一个成员函数
那么此时,它的形式就会有所变化
#include<iostream>
using namespace std;
class Date {
public:Date(int year = 1, int month = 1,int day=1) {_year = year;_month = month;_day = day;}bool operator==( const Date& d) {if (_year == d._year && _month == d._month && _day == d._day) {return true;}return false;}
private:int _year;int _month;int _day;
};int main() {Date d1(2023, 3, 1);Date d2;int ret = d1.operator==(d2);cout << ret << endl;return 0;
}
这里的d1是利用构造函数去初始化了,d2没有传值就是去调用默认构造函数,实际上就是利用缺省值去进行初始化。调用成员函数就像主函数第三行一样,因为编译器会默认传一个this指针
既然我们都这么写了,那么我们能不能再简化一点呢?
其实我们可以直接用符号去比较的
int main() {Date d1(2023, 3, 1);Date d2;int ret = d1 == d2;//int ret = d1.operator==(d2);cout << ret << endl;return 0;
}
这样写就会让编译器默认去调用下面的函数
有了运算符重载的知识,我们下面写一下赋值运算符重载,
Date& operator=(const Date& d) {if (this != &d) {_year = d._year;_month = d._month;_day = d._day;}return *this;}
这里要注意如果=左右是一个对象的话是不需要去赋值的,并且用的是引用返回不需要拷贝,有返回值是因为有可能要连续赋值,就像下边
d1=d1;
d1=d2=d3;
赋值运算符重载函数和拷贝构造函数是一样的,对于内置类型会去调用默认的函数,对于自定义类型会去调用自定义类型定义好的函数
相关文章:
【C++】类和对象——拷贝构造和赋值运算符重载
上一篇我们讲了构造函数,就是对象实例化时会自动调用,那么,我们这里的拷贝构造在形式上是构造函数的一个重载,拷贝构造其实也是一种构造函数,那么我们就可以引出这里的规则 1.拷贝构造函数的函数名必须与类名相同。 2.…...
基于acme免费申请泛域名证书
参考文档:https://github.com/acmesh-official/acme.sh 文章目录 step1: 获取阿里云的ak、skstep2: 安装acmestep3: 安装通配符证书step4: 查看证书step5: 证书的使用step6: 删除证书 step1: 获取阿里云的ak、sk export Ali_Key"LTAI5tG8888888CDoEjLzkE"…...
系列十九、Spring实例化bean的方式
一、概述 所谓实例化bean,大白话讲就是Spring如何把这一个个的普通的Java对象创建为Spring bean的。 二、方式 Spring中实例化bean常用的有以下四种,即: ① 构造器方式; ② 静态工厂方式; ③ 实例工厂方式;…...
WordPress无插件实现css、js加速 实现动静态分离
“Wordpress网站现在普遍较慢”,其实是没有做好优化罢了,像我的网站生成页面的时间才0.06s,而且我这网站还有提速的机会呢,如css、js使用CDN加速,实现动静态分离,我安装过,Memcache和PHP加速脚本就已经让我…...
2017年五一杯数学建模B题自媒体时代的消息传播问题解题全过程文档及程序
2017年五一杯数学建模 B题 自媒体时代的消息传播问题 原题再现 电视剧《人民的名义》中人物侯亮平说:“现在是自媒体时代,任何突发性事件几分钟就传播到全世界。”相对于传统媒体,以互联网技术为基础的自媒体以其信息传播的即时性、交往方式…...
虹科分享 | AR世界揭秘:从二维码的起源到数据识别与位姿技术的奇妙融合!
引言:探索AR的神奇世界,我们将从二维码的诞生谈起。在这个科技的海洋中,二维码是如何帮助AR实现数据获取与位姿识别的呢?让我们一起揭开这层神秘的面纱! 一、二维码的由来 二维码是将数据存储在图形中的技术ÿ…...
基于helm部署并配置StorageClass
此类方法适用于测试环境或者小型的集群环境,因为nfs是网络文件系统,在io性能上并不能有所保证。 前置条件: 已部署k8s集群已安装helm 工具 step1: 安装nfs服务 yum install nfs-utils -ystep2: 配置nfs # 编辑/etc/exports /data/nfs *(r…...
Python基础:字符串详解(需补充完善)
1. 字符串定义 在Python中,字符串是一种数据类型,用于表示文本数据。字符串是由字符组成的序列,可以包含字母、数字、符号和空格等字符。在Python中,你可以使用单引号()或双引号("&#x…...
做直播服务器要什么样的配置呢?
现在直播行业越来越火爆,大大小小的平台或者企业都选择通过直播卖货的方式出售产品,直播的内容还有观看直播的人数等等都影响了服务器的配置需求,今天小编就给大家讲一讲吧! 1、内存:直播服务器需要足够的内存才能支持…...
⑥【bitmap 】Redis数据类型: bitmap [使用手册]
个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ Redis bitmap ⑥Redis bitmap 基本操作命令1. …...
CentOS升级GCC
背景 CentOS 7默认自带GCC版本4.8,而目前工作中开发环境需要用到GCC8和GCC12,这里记录一下如何升级GCC版本,以及如何多版本并存。参考: CentOS升级gcc-知乎 Redhat7上安装Red Hat Developer Toolset并自由切换gcc和g的版本 Cent…...
CodeWhisperer 体验总结
CodeWhisperer 体验总结 | CodeWhisperer 是一款亚马逊新推出的通用代码生成器 可以实时进行代码数据的提供 还可以定义安全问题 CodeWhisperer 对个人用户是免费使用 企业用户需要订阅使用 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例…...
Apache换行解析漏洞(CVE-2017-15715)
漏洞简介 Apache換行解析漏洞(CVE-2017-15715)是一种解析漏洞,可以影响httpd 2.4.0至2.4.29版本中的PHP解析。攻击者可以通过在上传的文件名中添加特定的换行符,绕过服务器的安全策略,使其被解析成PHP文件而不是普通文件。此漏洞会影响具有以下条件的服务器: 未正确配置…...
人工智能时代的内容写作
内容不再只是王道,正如俗话所说:它是一种流动的货币,推动了巨大的在线信息和影响力经济。 每个品牌都是一个故事,通过其服务和商品讲述自己。尽管如此,大多数客户还是会通过您的在线内容最了解您。 但随着我们进入人…...
ASM字节码操作类库(打开java语言世界通往字节码世界的大门) | 京东云技术团队
前言:授人以鱼不如授人以渔,应用asm的文章有很多,简单demo的也很多,那么ASM都具备哪些能力呢?如何去学习编写ASM代码呢?什么样的情景需要用到ASM呢?让我们带着这些问题阅读这篇文章吧。 这里由…...
SpringBoot 拦截器高级篇
Springboot 拦截器 定义使用场景拦截器与过滤器的区别实现步骤全局拦截器的局限性全局拦截器VS局部拦截器局部拦截器自定义局部拦截器使用多个局部拦截器 定义 拦截器是Spring MVC框架中的一个重要组件,它是一种AOP(面向切面编程)的实现方式&…...
Android frameworks 开发总结之十(lock screen message Battery Last full charge)
1.設置lock screen message後不显示 XXXt設備設置lock screen message後,發現鎖頻界面不顯示內容,像時間日期都不顯示。只在右上角顯示一個鎖圖標,需要向下滑動一下才能顯示出來。布局文件位置: frameworks/base/packages/SystemUI/res-keygu…...
[建议收藏] 一个网站集合所有最新最全的AI工具
今天给大家推荐一个宝藏的AI工具合集网站,有了这个网站,你们再也不用去其他地方找AI工具了。 名称:AI-BOT工具集 这个网站精选1000AI工具,并持续每天更新添加,包括AI写作、AI绘画、AI音视频处理、AI平面设计、AI自动编…...
嵌入式硬件基础知识——1
目录 SOC、MCU、MPU、CPU SPI STM32的时钟系统 can是什么 串口和并口 传感器输出引脚高阻抗好还是低阻抗好? iic 运算放大器特点 MOS管和三极管 同步电路和异步电路 SOC、MCU、MPU、CPU SOC 片上系统 手机的核心芯片 MCU 微控系统 单片机 MPU 嵌入式微处…...
Spring如何在多线程下保持事务的一致性
Spring如何在多线程下保持事务的一致性 方法:每个线程都开启各自的事务去执行相关业务,等待所有线程的业务执行完成,统一提交或回滚。 下面我们通过具体的案例来演示Spring如何在多线程下保持事务的一致性。 1、项目结构 2、数据库SQL CR…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
