【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…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...
【题解-洛谷】P10480 可达性统计
题目:P10480 可达性统计 题目描述 给定一张 N N N 个点 M M M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。 输入格式 第一行两个整数 N , M N,M N,M,接下来 M M M 行每行两个整数 x , y x,y x,y,表示从 …...
