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

【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++】类和对象——拷贝构造和赋值运算符重载

上一篇我们讲了构造函数&#xff0c;就是对象实例化时会自动调用&#xff0c;那么&#xff0c;我们这里的拷贝构造在形式上是构造函数的一个重载&#xff0c;拷贝构造其实也是一种构造函数&#xff0c;那么我们就可以引出这里的规则 1.拷贝构造函数的函数名必须与类名相同。 2.…...

基于acme免费申请泛域名证书

参考文档&#xff1a;https://github.com/acmesh-official/acme.sh 文章目录 step1: 获取阿里云的ak、skstep2: 安装acmestep3: 安装通配符证书step4: 查看证书step5: 证书的使用step6: 删除证书 step1: 获取阿里云的ak、sk export Ali_Key"LTAI5tG8888888CDoEjLzkE"…...

系列十九、Spring实例化bean的方式

一、概述 所谓实例化bean&#xff0c;大白话讲就是Spring如何把这一个个的普通的Java对象创建为Spring bean的。 二、方式 Spring中实例化bean常用的有以下四种&#xff0c;即&#xff1a; ① 构造器方式&#xff1b; ② 静态工厂方式&#xff1b; ③ 实例工厂方式&#xff1b;…...

WordPress无插件实现css、js加速 实现动静态分离

“Wordpress网站现在普遍较慢”&#xff0c;其实是没有做好优化罢了&#xff0c;像我的网站生成页面的时间才0.06s,而且我这网站还有提速的机会呢&#xff0c;如css、js使用CDN加速&#xff0c;实现动静态分离&#xff0c;我安装过&#xff0c;Memcache和PHP加速脚本就已经让我…...

2017年五一杯数学建模B题自媒体时代的消息传播问题解题全过程文档及程序

2017年五一杯数学建模 B题 自媒体时代的消息传播问题 原题再现 电视剧《人民的名义》中人物侯亮平说&#xff1a;“现在是自媒体时代&#xff0c;任何突发性事件几分钟就传播到全世界。”相对于传统媒体&#xff0c;以互联网技术为基础的自媒体以其信息传播的即时性、交往方式…...

虹科分享 | AR世界揭秘:从二维码的起源到数据识别与位姿技术的奇妙融合!

引言&#xff1a;探索AR的神奇世界&#xff0c;我们将从二维码的诞生谈起。在这个科技的海洋中&#xff0c;二维码是如何帮助AR实现数据获取与位姿识别的呢&#xff1f;让我们一起揭开这层神秘的面纱&#xff01; 一、二维码的由来 二维码是将数据存储在图形中的技术&#xff…...

基于helm部署并配置StorageClass

此类方法适用于测试环境或者小型的集群环境&#xff0c;因为nfs是网络文件系统&#xff0c;在io性能上并不能有所保证。 前置条件&#xff1a; 已部署k8s集群已安装helm 工具 step1: 安装nfs服务 yum install nfs-utils -ystep2: 配置nfs # 编辑/etc/exports /data/nfs *(r…...

Python基础:字符串详解(需补充完善)

1. 字符串定义 在Python中&#xff0c;字符串是一种数据类型&#xff0c;用于表示文本数据。字符串是由字符组成的序列&#xff0c;可以包含字母、数字、符号和空格等字符。在Python中&#xff0c;你可以使用单引号&#xff08;&#xff09;或双引号&#xff08;"&#x…...

做直播服务器要什么样的配置呢?

现在直播行业越来越火爆&#xff0c;大大小小的平台或者企业都选择通过直播卖货的方式出售产品&#xff0c;直播的内容还有观看直播的人数等等都影响了服务器的配置需求&#xff0c;今天小编就给大家讲一讲吧&#xff01; 1、内存&#xff1a;直播服务器需要足够的内存才能支持…...

⑥【bitmap 】Redis数据类型: bitmap [使用手册]

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Redis bitmap ⑥Redis bitmap 基本操作命令1. …...

CentOS升级GCC

背景 CentOS 7默认自带GCC版本4.8&#xff0c;而目前工作中开发环境需要用到GCC8和GCC12&#xff0c;这里记录一下如何升级GCC版本&#xff0c;以及如何多版本并存。参考&#xff1a; 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文件而不是普通文件。此漏洞会影响具有以下条件的服务器: 未正确配置…...

人工智能时代的内容写作

内容不再只是王道&#xff0c;正如俗话所说&#xff1a;它是一种流动的货币&#xff0c;推动了巨大的在线信息和影响力经济。 每个品牌都是一个故事&#xff0c;通过其服务和商品讲述自己。尽管如此&#xff0c;大多数客户还是会通过您的在线内容最了解您。 但随着我们进入人…...

ASM字节码操作类库(打开java语言世界通往字节码世界的大门) | 京东云技术团队

前言&#xff1a;授人以鱼不如授人以渔&#xff0c;应用asm的文章有很多&#xff0c;简单demo的也很多&#xff0c;那么ASM都具备哪些能力呢&#xff1f;如何去学习编写ASM代码呢&#xff1f;什么样的情景需要用到ASM呢&#xff1f;让我们带着这些问题阅读这篇文章吧。 这里由…...

SpringBoot 拦截器高级篇

Springboot 拦截器 定义使用场景拦截器与过滤器的区别实现步骤全局拦截器的局限性全局拦截器VS局部拦截器局部拦截器自定义局部拦截器使用多个局部拦截器 定义 拦截器是Spring MVC框架中的一个重要组件&#xff0c;它是一种AOP&#xff08;面向切面编程&#xff09;的实现方式&…...

Android frameworks 开发总结之十(lock screen message Battery Last full charge)

1.設置lock screen message後不显示 XXXt設備設置lock screen message後&#xff0c;發現鎖頻界面不顯示內容&#xff0c;像時間日期都不顯示。只在右上角顯示一個鎖圖標&#xff0c;需要向下滑動一下才能顯示出來。布局文件位置: frameworks/base/packages/SystemUI/res-keygu…...

[建议收藏] 一个网站集合所有最新最全的AI工具

今天给大家推荐一个宝藏的AI工具合集网站&#xff0c;有了这个网站&#xff0c;你们再也不用去其他地方找AI工具了。 名称&#xff1a;AI-BOT工具集 这个网站精选1000AI工具&#xff0c;并持续每天更新添加&#xff0c;包括AI写作、AI绘画、AI音视频处理、AI平面设计、AI自动编…...

嵌入式硬件基础知识——1

目录 SOC、MCU、MPU、CPU SPI STM32的时钟系统 can是什么 串口和并口 传感器输出引脚高阻抗好还是低阻抗好&#xff1f; iic 运算放大器特点 MOS管和三极管 同步电路和异步电路 SOC、MCU、MPU、CPU SOC 片上系统 手机的核心芯片 MCU 微控系统 单片机 MPU 嵌入式微处…...

Spring如何在多线程下保持事务的一致性

Spring如何在多线程下保持事务的一致性 方法&#xff1a;每个线程都开启各自的事务去执行相关业务&#xff0c;等待所有线程的业务执行完成&#xff0c;统一提交或回滚。 下面我们通过具体的案例来演示Spring如何在多线程下保持事务的一致性。 1、项目结构 2、数据库SQL CR…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...