7.C++面向对象3(拷贝构造函数,赋值运算符重载)

⭐本篇为C++学习第7章,主要了解 拷贝构造函数,赋值运算符重载

⭐本人Gitee C++代码仓库:yzc的c++学习: 小川c++的学习记录 - Gitee.com 

上篇讲了6个默认成员函数的构造函数和析构函数。

重要代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;class Date
{
public:Date(int year = 0, int month = 0, int day = 0){_year = year;_month = month;_day = day;}~Date(){}void print(){cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{return 0;
}

一. 拷贝构造函数

a 拷贝构造函数是构造函数的一个重载,用于对象的拷贝并且初始化

如: 

Data d1(2024,10,1);
Data d2(d1);

b 拷贝构造函数在的参数只有一个且必须使用引用传参,传值会导致无穷递归调用

c 如果用户没有显示定义,编译器会生成默认的拷贝构造函数,但这个函数以内存存储,字节序进行浅拷贝

若使用按值传参会导致无穷递归调用

如:

这是因为传参的时候,需要调用拷贝构造函数对参数进行拷贝,又需要调用拷贝构造函数

正确写法如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;class Date
{
public:Date(int year = 0, int month = 0, int day = 0){_year = year;_month = month;_day = day;}Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}~Date(){}void print(){cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 10, 11);Date d2(d1);d1.print();d2.print();return 0;
}

 使用引用传参可以防止无穷递归问题,再使用const可以防止修改d中的内容

运行结果如下:

和析构函数一样,拷贝构造函数也存在深浅拷贝问题。

如果我们在堆上申请空间,并且使用了浅拷贝。这就会导致同一块地址空间被析构两次而报错

二. 运算符重载

2.1 其他运算符重载

在了解赋值运算符重载之前要知道什么是运算符重载。

c++为了增强代码可读性引入了运算符重载,运算符重载也是一种函数

函数原型: 返回值类型 operator 运算符符号

运算符符号:如 + - * / == > < 等

为什么要有运算符重载??

        比如我们定义了一个日期类,如何判读两个日期对象是否相等??如何比较两个日期的大小??

如:

很明显需要我们需要自己定义 == 来完成这个功能

==运算符重载

 所以我们很容易写出下面的函数原型,但是这是错误的!

	bool operator==(const Date& d1, const Date& d2){}

因为我们调用的方式是 d1 == d2

        d1 == d2 明显是d1去调用==这个函数来判断和d2是否相等,所以d1已经被this指针传入了,我们无需再传入

正确方法如下:

	bool operator==(const Date& d){//通过this指针来传入第一个参数return this->_year = d._year&& this->_month = d._month&& this->_day = d._day;}

测试

>运算符重载

	bool operator > (const Data& d){if (_year > d._year)return true;else if (_year == d._year && _month > d._month)return true;else if (_year == d._year && _month == d._month && _day > d._day)return true;elsereturn false; }

有了==运算符重载可以轻易写入>运算符重载,体现了代码的复用

<运算符重载

由>运算符重载,我们能轻易写入<运算符重载

	bool operator<(const Date& d){if (_year < d._year)return true;else if (_year == d._year && _month < d._month)	//这里直接调用==重载符return true;else if (_year == d._year && _month == d._month && _day < d._day)return true;elsereturn false;}

2.2 赋值运算符重载

赋值运算符重载的意义是用一个对象赋值给另一个对象。

赋值运算符重载和拷贝构造函数要区分。

由于赋值运算符重载是6个默认成员函数之一,如果用户没有自定义,系统会按字节序进行浅拷贝

int main()
{Date d1(2024, 10, 11);Date d2(1, 1, 1);d2 = d1;	//赋值运算符重载,d2已经初始化Date d3(d1);//拷贝构造,d3还没有初始化return 0;
}
	void operator=(const Date& d){//如果this指向对象的地址和d的地址不一样才能进行赋值//如果地址一样说明二者相等(不仅仅是值相同,连内存地址都一样!),无需赋值//我们需要完成的是深拷贝,两个对象仅仅是值相同,内存地址不一样if (this != &d){this->_year = d._year;this->_month = d._month;this->_day = d._day;}}

简单测试:

但是上面代码还完美。比如我们经常有下列操作

按照上面的写法会报错,因为我们返回值是void

当(d2=d1)后执行 d3=void,这显然是不对的。我们需要返回d2才能完成 d3=d2

	//使用引用返回可以减少拷贝,增加效率Date& operator=(const Date& d){//如果this指向对象的地址和d的地址不一样才能进行赋值//如果地址一样说明二者相等(不仅仅是值相同,连内存地址都一样!),无需赋值if (this != &d){this->_year = d._year;this->_month = d._month;this->_day = d._day;}//this执行被赋值的对象,解引用就能找到它return *this;}

简单测试

可以看到,能够完成多次赋值

注意:

a.不能连接其他操作符构成新的操作符如operator@
b.重载操作符必须用于自定义类类型
c.用于内置类型的操作符,其含义不可改变,如+不能改变含义
d.作为类成员的重载函数时,其参数要少一个。由于有一个默认参数this
e.   .*	::	sizeof	:?	.  这五个操作符不可重载

三.下章重点

3.1 const成员

3.2 取地址重载 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/444224.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql(五) --- 数据库设计

文章目录 前言1.范式1.1.第一范式1.1.1 定义1.1.2.例子 1.2.第二范式1.2.1 定义1.2.2 例子1.2.3.不满足第二范式可能会出现的问题 1.3.第三范式1.3.1 定义2.3.2 示例 2. 设计过程3. 实体-关系图3.1 E-R图的基本组成3.2 关系的类型3.2.1 一对一关系(1:1)3.2.2 ⼀对多关系(1:N)3.…

Pr:视频效果快速参考(合集 · 2024版)

Premiere Pro 自带十七组约一百多个视频效果&#xff0c;涵盖了从变换、颜色控制到风格化等多种用途&#xff0c;帮助用户在视频编辑中实现多样化的视觉表现、进行后期处理以及修正各种画质问题。 提示&#xff1a; 点击下面的效果组名称或截图&#xff0c;即可访问该组里面的效…

SF6气体密度监测仪市场研究:主要企业的市场份额已超过37.13%

SF6气体密度监测仪是一种专用于监测和测量六氟化硫&#xff08;SF6&#xff09;气体密度的设备。SF6气体因其优异的绝缘性能和灭弧能力&#xff0c;被广泛应用于电力行业&#xff0c;尤其是在气体绝缘金属封闭开关设备&#xff08;GIS&#xff09;和断路器等关键设备中。随着电…

【自注意力与Transformer架构在自然语言处理中的演变与应用】

背景介绍 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;序列到序列&#xff08;seq2seq&#xff09;模型和Transformer架构的出现&#xff0c;极大地推动了机器翻译、文本生成和其他语言任务的进展。传统的seq2seq模型通常依赖于循环神经网络&#xff08;RNN&…

微服务Sleuth解析部署使用全流程

目录 1、Sleuth链路追踪 1、添加依赖 2、修改日志配置文件 3、测试 2、zipkin可视化界面 1、docker安装 2、添加依赖 3、修改配置文件 4、查看页面 5、ribbon配置 1、Sleuth链路追踪 sleuth是链路追踪框架&#xff0c;用于在微服务架构下开发&#xff0c;各个微服务之…

刷题 - 分治

面试经典 150 题 - 分治 148. 排序链表⭐️⭐️⭐️ - 快慢指针找中间节点 - 归并排序 伪代码&#xff1a; 将链表拆分成两半&#xff0c;返回右半边头节点&#xff08;左半边头节点就是原始链表头节点&#xff09;对左边进行排序并返回左边头节点对右边进行排序返回右边头节…

使用jenkins将airflow-dbt部署到服务器上

系列文章目录 文章目录 系列文章目录课程地址YT一、jenkins服务器的初始化配置1.1 运行第一个jenkins pipeline二、编写本地dbt项目2.1 克隆git上的初始文件到本地2.2 本地创建虚拟环境2.3 创建airflow的Dockerfile2.4 安装dbt2.5 创建dbt所需要的snowflake数据库2.6 配置docke…

Android开发视频预览效果

Android开发视频预览效果 视频播放不是一个简单的事情&#xff0c;得有暂停&#xff0c;继续播放等功能&#xff0c;屏幕的适配也是头疼的事情 一、思路&#xff1a; 引用的是腾讯播放器TXVodPlayer 二、效果图&#xff1a; 图片不是很直观&#xff0c;也可以看下视频 And…

渗透测试 之 域渗透手法【域内用户枚举】手法 Kerbrute msf pyKerbrute 工具使用详解

说明一下: 域内用户枚举工具使用说说&#xff1a; Kerbrute pyKerbrute MSF模块的使用 域内用户名枚举原理分析&#xff1a; 域内用户枚举攻击防御&#xff1a; 流量检测&#xff1a; 日志层面&#xff1a; 说明一下: 域环境或者内网环境下&#xff0c;可以在没有域环…

npm ERR! PhantomJS not found on PATH

安装phantomj时发生报错 old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. npm ERR! code 1 npm ERR! path /va…

四、Spring Boot集成Spring Security之认证流程

Spring Boot集成Spring Security之认证流程 一、概要说明二、基于内存的用户名密码1、默认用户名密码2、自定义用户名密码3、为方便测试添加测试接口TestController 三、登录登出重要概念介绍四、登录业务逻辑1、登录业务相关过滤器2、访问业务请求处理流程①、访问业务请求地址…

kubernetes中微服务部署

微服务 问&#xff1a;用控制器来完成集群的工作负载&#xff0c;那么应用如何暴漏出去&#xff1f; 答&#xff1a;需要通过微服务暴漏出去后才能被访问 Service 是一组提供相同服务的Pod对外开放的接口借助Service&#xff0c;应用可以实现服务发现和负载均衡Service 默认只…

初学Qt之环境安装与 hello word

环境&#xff1a; Qt Creator 4.11.0 (Community) Qt 5.14.0 目录 1.Qt环境配置 1.1 下载Qt 5.14.0 1.2 注册Qt账号 1.3 安装Qt 1.4 配置环境变量 2.创建项目 2.1 创建一个项目 2.2 初始代码解析 2.3 可视化GUI ​编辑 2.4 hello word 2.4.1 可视化hello word …

链式二叉树及二叉树各种接口的实现(C)

二叉树的性质 若规定根节点的层数为1&#xff0c;则一棵非空二叉树的第 i i i层上最多有 2 i − 1 2^{i-1} 2i−1个结点.若规定根节点的层数为1&#xff0c;则深度为h的二叉树的最大结点数是 2 h − 1 2^{h}-1 2h−1对任何一棵二叉树&#xff0c;如果度为0其叶结点个数为 n 0 …

Koa学习

Koa 安装与配置 1. 初始化项目 在终端中执行以下命令&#xff1a; # 创建项目文件夹 mkdir koa cd koa# 初始化并安装依赖 npm init -y npm install koa npm install nodemon --save-dev2. 修改 package.json 在 package.json 文件中进行如下修改&#xff1a; {"type…

C语言 | Leetcode C语言题解之第472题连接词

题目&#xff1a; 题解&#xff1a; typedef struct Trie {struct Trie * children[26];bool isEnd; }Trie;#define TRIE_INITIAL(node) do { \for (int i 0; i < 26; i) { \(node)->children[i] NULL; \} \(node)->isEnd false; \ }while(0);static void freeTri…

互联网线上融合上门洗衣洗鞋小程序,让洗衣洗鞋像点外卖一样简单

随着服务创新的风潮&#xff0c;众多商家已巧妙融入预约上门洗鞋新风尚&#xff0c;并携手洗鞋小程序&#xff0c;开辟线上蓝海。那么&#xff0c;这不仅仅是一个小程序&#xff0c;它究竟蕴含着哪些诱人好处呢&#xff1f; 1. 无缝融合&#xff0c;双线共赢&#xff1a;小程序…

美团Java一面

美团Java一面 9.24一面&#xff0c;已经寄了 收到的第一个面试&#xff0c;表现很不好 spring bean生命周期 作用域&#xff08;忘完了&#xff09; 为什么用redis缓存 redis和数据库的缓存一致性问题 redis集群下缓存更新不一致问题 aop说一下 arraylist和linkedlist 数据库的…

2024年软件设计师中级(软考中级)详细笔记【5】软件工程基础知识上(分值10+)

第5章软件工程 目录 前言第5章 软件工程基础知识&#xff08;上&#xff09;&#xff08;分值10&#xff09;5.1 软件工程概述5.1.4 软件过程 5.2 软件过程模型5.2.1 瀑布模型 (Waterfall Model)5.2.2 增量模型5.2.3 演化模型5.2.4 喷泉模型&#xff08;Water Fountain Model&a…

JavaScript下载文件(简单模式、跨域问题、文件压缩)

文章目录 简介简单文件下载通过模拟form表单提交通过XMLHttpRequest方式 跨域(oss)下载并压缩文件完整示例文件压缩跨域设置 简介 相信各位开发朋友都遇到过下载的文件的需求&#xff0c;有的非常简单&#xff0c;基本链接的形式就可以。 有的就比较复杂&#xff0c;涉及跨域…