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

C++ 拷贝构造函数和运算符重载

目录

一. 拷贝构造函数

1. 引入

2. 拷贝构造的概念

3. 浅拷贝

4. 深拷贝

二. C++运算符重载 

1. 概念 

2. 注意事项 

3.举例 


一. 拷贝构造函数

1. 引入

我们在创建对象时,能不能创建一个与原先对象一模一样的新对象呢?为了解决这个问题,C++提出了拷贝构造的概念。

2. 拷贝构造的概念

当我们想把一个对象赋值给另一个对象或者创建一个与已存在对象一某一样的新对象时需要调用它的拷贝函数来进行复制。我们以下面的代码举例:

#include<iostream>
using namespace std;class Date 
{
public:Date(int year = 2024, int month = 3, int day = 14){_year = year;_month = month;_day = day;}// Date(const Date d)    // 错误写法:编译报错,会引发无穷递归Date(const Date& d)//拷贝构造函数{_year = d._year;_month = d._month;_day = d._day;}
private:int _year;int _month;int _day;
};int main()
{Date d1;Date d2(d1);
//这样写也可以:Date d2 = d1;return 0;
}

拷贝构造函数也是特殊的成员函数,其特征如下:

1. 拷贝构造函数是构造函数的一个重载形式。

2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错, 因为会引发无穷递归调用

为什么会引发无穷递归呢?是因为如果我们传值当形参的话那么形参是实参的一份临时拷贝又会拷贝构造函数这样就会无限递归下去。

所以我们在书写构造函数的时候一定要使用传引用当做形参。 

 

3. 浅拷贝

我们知道C语言函数在传递参数时,会将实参的值传递给形参,中间自动存在一个变量的临时拷贝过程,那如果我们不写拷贝构造函数,编译器会发生什么情况呢?

我们发现仍然完成了值拷贝。这是因为拷贝构造函数没有显示定义的化,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。需要注意的是,在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。

4. 深拷贝

编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?我们来看下面的代码:

typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申请空间失败");return;}_size = 0;_capacity = capacity;}void Push(const DataType& data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}
private:DataType* _array;size_t _size;size_t _capacity;
};
int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2(s1);return 0;
}

这里刚开始创建了一个S1 对象,又创建了一个S2 对象去进行调用拷贝构造函数进行拷贝,而这里只进行了浅拷贝,在 S2 进行拷贝构造的时候只是简单的把值复制过去了所以 S2 和 S1 是指向同一块空间并没有给 S2 去单独开辟一个一模一样的空间。那为什么程序回出现崩溃呢?

S2 和 S1 指向用一块空间而当程序结束的时候 S2 调用它的析构函数去吧 S1 所指向的空间给释放了, 那么当 S1 在释放的时候就重复释放了原来释放的空间导致程序崩溃。一块空间不能被释放两次。

因此我们我们需要进行深拷贝:

#include<iostream>
#include<stdlib.h>
using namespace std;class Stack
{
public:Stack(size_t capacity = 10){_array = (int*)malloc(capacity * sizeof(int));if (nullptr == _array){perror("malloc申请空间失败");return;}_size = 0;_capacity = capacity;}Stack(const Stack& p1){int* tmp = (int*)malloc(sizeof(int) * p1._capacity);if (tmp == nullptr){perror("file malloc");exit(-1);			}memcpy(tmp, p1._array, sizeof(int) * p1._size);_array = tmp;_capacity = p1._capacity;_size = p1._size;}void Push(const int& data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}
private:int* _array;size_t _size;size_t _capacity;
};
int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2(s1);return 0;
}

所以我们需要动态申请空间,显示定义拷贝构造函数,把空间大小和值内容拷贝进去。

因此我们有以下总结: 

类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请 时,则拷贝构造函数是一定要写的,否则就是浅拷贝。拷贝构造函数典型调用场景:使用已存在对象创建新对象 函数参数类型为类类型对象 ,函数返回值类型为类类型对象。

二. C++运算符重载 

1. 概念 

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其 返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。 函数名字为:关键字operator后面接需要重载的运算符符号。

函数原型:返回值类型 operator操作符(参数列表)

2. 注意事项 

 不能通过连接其他符号来创建新的操作符:比如operator@

重载操作符必须有一个类类型参数 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不能改变其含义

作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this

以上下个运算符不能重载:

3.举例 
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}int _year;int _month;int _day;
};bool operator==(const Date& d1, const Date& d2)
{return d1._year == d2._year&& d1._month == d2._month&& d1._day == d2._day;
}int main()
{Date d1(2024, 3, 14);Date d2(2024, 3, 15);cout << (d1 == d2) << endl;return 0;
}


相关文章:

C++ 拷贝构造函数和运算符重载

目录 一. 拷贝构造函数 1. 引入 2. 拷贝构造的概念 3. 浅拷贝 4. 深拷贝 二. C运算符重载 1. 概念 2. 注意事项 3.举例 一. 拷贝构造函数 1. 引入 我们在创建对象时&#xff0c;能不能创建一个与原先对象一模一样的新对象呢&#xff1f;为了解决这个问题&#x…...

二刷代码随想录算法训练营第二十三天 | 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

目录 一、669. 修剪二叉搜索树 二、108. 将有序数组转换为二叉搜索树 三、538. 把二叉搜索树转换为累加树 一、669. 修剪二叉搜索树 题目链接&#xff1a;力扣 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a; 你修剪的方式不对&#xff0c;我来给你纠正一下&#…...

信息抽取在旅游行业的应用:以景点信息抽取为例

开源项目推荐 今天先给大家推荐一个开源项目&#xff0c;多模态AI能力引擎平台: 免费的自然语言处理、情感分析、实体识别、图像识别与分类、OCR识别、语音识别接口&#xff0c;功能强大&#xff0c;欢迎体验。 https://gitee.com/stonedtx/free-nlp-api 场景描述 在旅游行业…...

Linux——基础指令

一、Linux目录结构 1、树形结构 Linux只有一个根目录 / &#xff0c;所有文件都在它下面 2、Linux路径的描述方式 在Linux系统中&#xff0c;路径之间的层级关系&#xff0c;使用&#xff1a; / 来表示 eg&#xff1a; /usr/local/hello.txt 注意&#xff1a; 开头/表示根…...

H5 带网站测速引导页源码

源码名称&#xff1a;带网站测速引导页源码 源码介绍&#xff1a;一款带网站测速功能的引导页源码 需求环境&#xff1a;H5 下载地址&#xff1a; https://www.changyouzuhao.cn/10717.html...

案例分析篇07:数据库设计相关28个考点(23~28)(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…...

Word中解决插入脚注导致的分页位置错误问题

先放一个截图&#xff1a; 上面的截图中&#xff0c;样式为标题3的段落“四、固执的念头”前插入了连续型分节符&#xff0c;并且该分节符的样式为正文&#xff0c;前后的正文段落中有脚注&#xff0c;结果在分页时&#xff0c;标题3段落“四、固执的念头”后的正文段落自动进入…...

2024/03/14(网络编程·day2)

一、思维导图 二、TCP通信 //服务器 #include<myhead.h>#define SER_PORT 8888 //服务器端口号 #define SER_IP "192.168.117.103" //服务器IP int main(int argc, const char *argv[]) {//1、创建一个套接字int sfd -1;sfd socket(AF_INET,SOCK_STREAM,…...

2024最新陪诊小程序/医院陪诊滴嗒陪诊小程序源码-陪护服务平台陪诊师陪

.系统介绍: 陪护小程序、微信陪诊、、ThinkPHP框架、ThinkPHP6框架、FastAdmin框架、微信小程序。 嘀嗒陪诊小程序功能相对简单,后台也简捷,如果只是做个陪诊服务的小程序也基本能满足了,整体测试了未发现BUG,小程序端也能正常为使用,用户授权接口是老的。 应用背景:人…...

基于单片机的温度控制系统设计

基于单片机的温度控制系统设计 摘要: 最近这些年&#xff0c;随着科学技术的不断发展和进步&#xff0c;单片机技术通过在各行各业中的应用也日臻完善。而温度测控系统也因单片机所特有的强大处理能力、功耗低以及体积小等优点向着小型化和智能化发展。本设计以STC89C52单片机…...

unity3d Animal Controller的Animal组件中Speeds,States和modes基础部分理解

Speeds 速度集是修改你可以做的原始动画,增加或减少运动,旋转,或动画速度。它们与 州 所以,当动物在运动状态下,在飞行或游泳时,你可以有不同的速度 如果你的性格动画是 (已到位), 你一定要调整速度 位置 和 旋转 每一种的价值观 速度装置 …否则,它们不会移动或旋转。 每个速…...

Tomcat详解

1Tomcat安装 下载 Tomcat&#xff1a;首先&#xff0c;您需要从 Tomcat 官方网站&#xff08;http://tomcat.apache.org&#xff09;下载适合您系统的最新版本的 Tomcat 软件包。通常情况下&#xff0c;您会选择一个稳定的版本进行下载。解压缩&#xff1a;下载完成后&#xf…...

SpringCloudAlibaba 网关gateway整合sentinel日志默认路径修改

SpringCloudAlibaba 网关gateway整合sentinel 实现网关限流熔断 问题提出 今天运维突然告诉我 在服务器上内存满了 原因是nacos日志高达3G,然后将日志文件发给我看了一下之后才发现是gateway整合sentinel使用了默认日志地址导致日志生成地址直接存在与根路径下而且一下存在多…...

#LLM入门|Prompt#3.3_存储_Memory

在与语言模型交互时&#xff0c;一个关键问题&#xff1a;记忆缺失使得对话缺乏真正的连续性。 因此&#xff0c;接下来介绍 LangChain 中的储存模块&#xff0c;即如何将先前的对话嵌入到语言模型中的&#xff0c;使其具有连续对话的能力。 当使用 LangChain 中的储存(Memory)…...

基于SSM+Vue的龙腾公司员工信息管理系统设计与实现

​ 1 绪论 1.1研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管理。这样的大环境让那些止步不前&a…...

使用点链云管家创建瑜伽约课小程序

点链云管家 点链云管家是由上海点链科技开发的门店管理系统&#xff0c;为线下门店商家提供一站式门店运营服务平台解决方案&#xff0c;适用于瑜伽健身、美业、新零售会员制电商、母婴店、宠物店、按摩养生、服装、美容、美甲、汽车服务、商超零售、餐饮、KTV娱乐、干洗等18个…...

【Node.js从基础到高级运用】八、Express 框架入门

Express 框架入门 Express 是一个灵活且广泛使用的 Node.js web 应用框架&#xff0c;它提供了一系列强大特性来帮助开发者创建各种 Web 和移动设备应用。在这一节中&#xff0c;我们将介绍如何安装和配置 Express&#xff0c;并简单探讨其路由和中间件的概念。 安装 Express…...

Unity Timeline学习笔记(2) - PlayableTrack

PlayableTrack 是可自定义播放的轨道。我们可以通过进入轨道后调用自己的函数方法&#xff0c;使用起来也是比较顺手的。 添加轨道 我们点击加号添加 这样就有一个空轨道了&#xff0c;然后我们创建两个测试脚本。 添加脚本 分别是Playable Behaviour和PlayableAsset脚本。…...

Linux的一些常用指令

一、文件中 r w x - 的含义 r&#xff08;read&#xff09;是只读权限&#xff0c; w&#xff08;write&#xff09;是写的权限&#xff0c; x&#xff08;execute&#xff09;是可执行权限&#xff0c; -是没有任何权限。 二、一些指令 # 解压压缩包 tar [-zxvf] 压缩包名…...

09-设计模式 企业场景 面试题

目录 1.简单工厂模式 ​编辑 2.工厂方法模式 3.抽象工厂模式 4.策略模式 5.登录案例(工厂模式+策略模式) 6.责任链设计模式 7.单点登录怎么是实现的? 8.权限认证是如何实现的 9.上传数据的安全性你们怎么控制? 10.你负责项目的时候遇到了哪些比较棘手的问题?怎…...

AI Agent如何重构数据分析工作流:从数据清洗到洞察生成的7步自动化闭环(附企业级架构图)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;AI Agent如何重构数据分析工作流&#xff1a;从数据清洗到洞察生成的7步自动化闭环&#xff08;附企业级架构图&#xff09; 传统数据分析依赖人工串联多个工具与脚本&#xff0c;耗时长、容错低、知识…...

SpringBoot+Vue旅游管理系统源码+论文

代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 分享万套开题报告任务书答辩PPT模板 作者完整代码目录供你选择&#xff1a; 《SpringBoot网站项目》1800套 《SSM网站项目》1500套 《小程序项目》1600套 《APP项目》1500套 《Python网站项目》…...

银行业务AI虚构小故事合集:借故事理解业务(企业贷款、个人信用卡、反洗钱)

银行业务AI虚构小故事合集 继续用之前讲业务故事的方式来讲银行业务和表的关联&#xff0c;那种方式比较容易听懂。 故事&#xff1a;一家小工厂来借钱 第一幕&#xff1a;企业来了&#xff0c;要借钱 杭州有一家做零件的小工厂&#xff0c;老板叫老张。工厂想买一台新机器&am…...

2025年终极指南:PlayIntegrityFix让你的Root设备完美通过Google认证

2025年终极指南&#xff1a;PlayIntegrityFix让你的Root设备完美通过Google认证 【免费下载链接】PlayIntegrityFix Fix Play Integrity (and SafetyNet) verdicts. 项目地址: https://gitcode.com/GitHub_Trending/pl/PlayIntegrityFix 还在为Root后的Android设备无法正…...

C++中多重继承详解及其作用介绍

多重继承 (multiple inheritance): 一个派生类有两个或多个基类, 派生类从两个或多个基类中继承所需的属性. C 为了适应这种情况, 允许一个派生类同时继承多个基类. 这种行为称为多重继承.优缺点优点自然地做到了对单继承的扩展可以继承多个类的功能缺点结构复杂化优先顺序模糊…...

【稀缺首发】全球仅12家头部科技公司验证的AI Agent机器学习架构(附可复用决策树模板)

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;AI Agent机器学习应用的范式跃迁 传统机器学习系统通常以静态模型为中心&#xff0c;依赖人工特征工程、离线训练与固定推理流程。而AI Agent的兴起正推动一场根本性范式跃迁&#xff1a;从“被动预测”转向“…...

AI Agent培训赋能金融/医疗/制造三大赛道(附2023真实训战数据与客户增效曲线)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;AI Agent培训赋能产业变革的底层逻辑 AI Agent并非传统意义上的自动化脚本&#xff0c;而是具备目标理解、环境感知、规划推理与工具调用能力的智能体。其产业赋能的底层逻辑&#xff0c;在于将人类专家…...

大麦网自动抢票神器:5分钟配置,告别抢票焦虑的终极指南

大麦网自动抢票神器&#xff1a;5分钟配置&#xff0c;告别抢票焦虑的终极指南 【免费下载链接】ticket-purchase 大麦自动抢票&#xff0c;支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase 还在为心仪演唱会门票…...

Java SE与Spring Boot在智慧城市中的应用

Java SE与Spring Boot在智慧城市中的应用 在互联网大厂求职的面试中&#xff0c;技术栈与场景应用是考察重点。今天&#xff0c;我们将通过一位搞笑程序员燕双非的面试经历来了解Java SE与Spring Boot在智慧城市中的应用。 第一轮面试 场景&#xff1a;智慧城市的背景 面试官&a…...

仓内与仓外智能物流设计技术难点

智能物流系统根据空间和边界可划分为仓内物流&#xff08;Intralogistics&#xff09;与仓外物流&#xff08;External Logistics&#xff09;。两者由于运行环境、控制变量和边界条件的根本差异&#xff0c;面临着截然不同的技术设计难点。一、 仓内智能物流设计技术难点&…...