C++ 类和对象 赋值运算符重载

前言:

在上文我们知道数据类型分为自定义类型和内置类型,当我想用内置类型比较大小是非常容易的但是在C++中成员变量都是在类(自定义类型)里面的,那我想给类比较大小那该怎么办呢?这时候运算符重载就出现了

一 运算符重载概念:

允许用户为自定义类定义或重新定义运算符的行为,使这些类在使用运算符时表现得像内置数据类型一样,从而提高代码的可读性和简洁性。

1.2 运算符重载与函数重载的区别:

我第一次听到这两个重载都傻傻的分不清楚,以为是一个意思。其实他们的区别可大了

函数重载:

函数重载是指在同一作用域中有多个同名函数,但它们的参数列表(参数的类型和数量)不同。编译器通过参数列表来决定调用哪个函数。函数重载的目的是为了提高代码的可读性和灵活性,使同一操作可以应用于不同类型的参数。

运算符重载:

运算符重载允许我们为用户定义的类型(如类)定义或重新定义特定运算符(如 +、-、*、/ 等)的行为。运算符重载函数的名称为 operator 后跟运算符符号。尽管这些函数的返回类型和参数列表与普通函数类似,但它们的目的是使自定义类型能够使用像内置类型一样的运算符

1.3 运算符特点:

1 定义运算符重载函数:运算符重载是通过定义特殊的成员函数全局函数来实现的

2 运算符重载函数的返回类型:通常是运算符操作后的结果类型。

3 运算符重载函数的参数:根据运算符的类型,参数可以是一个或多个。

4  * :: sizeof ?: . 注意以上5个运算符不能重载

3.1 代码解析:

运算符重载成员函数代码示例:

//成员函数 运算符重载
class Date 
{
public:int _x = 5;int _y = 4;int operator+(const Date& b){return this->_x + b._x + this->_y + b._y;}//错误写法//int operator+(const Date& a , const Date& b)/*{return a.x + b.x + a.y + b.y;}*/
};
int main()
{//成员函数 运算符重载Date d1;Date d2;int sum = d1 + d2;std::cout << "d1 d2总和:" << sum << std::endl;return 0;
}

错误写法分析:

因为它是Date类里面的成员函数 又因为成员函数会自带一个隐含的this指针所以成员函数版本的 operator+ 只能有一个显式参数。如果需要两个参数,则应使用全局函数版本的运算符重载。

//全局函数 运算符重载
class Point
{
public://默认构造函数Point(){this->_x = 5;this->_y = 15;}
//private:int _x;int _y;
};
bool operator==(const Point& b, const Point& a)
{return (b._x == a._x) && (b._y == a._y);
}int main()
{Point f1;Point f2;int B = f1 == f2;std::cout << "1相同 0相否:" << B << std::endl;return 0;
}

全局函数的运算符重载是在类外部实现的,不属于任何类,因此没有 this 指针。全局函数可以通过参数访问所有操作数。

假如我把成员函数变成私有的话那在全局函数里面就找不到他们了所以想改变就只能把运算符变量改为成员函数或者用友元函数或getter方法。

二 赋值运算符重载概念:

赋值运算符重载用于定义对象之间的赋值操作,即如何将一个对象的值赋给另一个对象。赋值运算符是 =,它在赋值时被调用。通常我们需要重载赋值运算符来处理深拷贝,以防止浅拷贝带来的问题。

2.1 赋值运算符重载和拷贝构造的区别:

通过赋值运算符重载的概念我们知道它主要的功能是将一个对象的值赋给另一个对象,而这和拷贝构造又非常相似,然而赋值运算符重载与运算符重载只有两字相差却又是不同的内容,这就让我很想知道他们之间的区别到底是什么,接下来让我们一起来解密吧!

概念:

1. 赋值运算符重载

定义对象之间的赋值操作,即如何将一个对象的值赋给另一个对象。

2. 运算符重载:

定义或重新定义自定义类型的运算符行为,使其与内置类型的运算符行为一致。

3. 拷贝构造:

创建一个新的对象,并将其初始化为现有对象的副本。

区别:

拷贝构造函数和赋值运算符重载的主要区别在于它们的使用场景和目的。拷贝构造函数在对象创建时用于初始化新对象,目的是创建一个新的副本。赋值运算符重载在对象已存在时用于赋值操作,目的是修改现有对象的状态,使其与另一个对象的状态相同。拷贝构造函数通常接收一个对同类对象的常引用,而赋值运算符重载通常返回对象的引用,并接收一个对同类对象的常引用作为参数。而运算符重载和赋值运算符重载也真是差了两个字而已,并没有什么区别。

2.1.0 代码解析:

//赋值运算符重载
class Date1
{
public://默认构造函数Date1(int year = 2005, int month = 5, int date = 25){this->_year = year;this->_month = month;this->_date = date;}//拷贝构造函数Date1(const Date1& other){this->_year = other._year;this->_month = other._month;this->_date= other._date;}//赋值运算符重载Date1 operator=(const Date1& d){this->_year = d._year;this->_month = d._month;this->_date = d._date;return *this;}//输出void print(){std::cout << _year << "-" << _month << "-" << _date << std::endl;}private:int _year;int _month;int _date;
};int main()
{//构造函数Date1 q1(2024 , 7 , 12);Date1 q2(2021 , 6 , 26);//拷贝构造Date1 q3(q2);//赋值运算符重载Date1 q4;q4 = q1;//输出q1.print();q2.print();q3.print();q4.print();return 0;
}

从上面代码可以知道q3是在被创建的时候就直接被调用拷贝构造初始化而q4是先定义好之后在被调用赋值运算符重载初始化的。

那既然赋值运算符重载就是对象之间的赋值那和C语言中的赋值整体意思还是一样的但就是赋值的对象变了,我不知道大家是否还记得在C语言中可以连续赋值,让我们来试试在C++中的赋值运算符重载是否也可以实现呢?

#include <iostream>
class Date 
{
public:int _year, _month, _day;Date(int year = 2005, int month = 5, int day = 25){this->_year = year;this->_month = month;this->_day = day;}// 赋值运算符重载Date& operator=(const Date& d) {// 自赋值检查if (this != &d) { _year = d._year;_month = d._month;_day = d._day;}return *this;   // 返回当前对象的引用}void Print(){std::cout << _year << "-" << _month << "-" << _day << std::endl;}
};int main() {Date d1(2023, 7, 10);Date d2;Date d3;// 链式赋值d3 = d2 = d1;d1.Print();  d2.Print(); d3.Print(); return 0;
}

输出:

虽然输出的结果确实是链式但是又有非常多的疑惑比如为什么要传*this 还有执行顺序是什么……

让我们详细的来解答一下:

首先d2传给隐函数this指针然后d1传给 Date& d那这时d1就是d的引用了,执行到下面就是判断成员变量的地址是否相同(最开始它们之间的地址还是不一样的)跳出循环之后就返回*this即d2的引用返回值类型  Date& (这个我之前一直没看到所以就很困惑)

2.2 默认赋值运算符重载:

编译器生成的默认赋值运算符重载也和默认构造函数中分自定义和内置类型那它与默认构造函数有什么区别,让我们一探究竟吧

内置类型:

概念:编译器生成的默认赋值运算符会直接逐字节拷贝内置类型成员变量的值。

代码演示:

//默认赋值运算符重载(内置类型)
class Date1
{
public://默认构造函数Date1(int year = 2005, int month = 5, int date = 25){this->_year = year;this->_month = month;this->_date = date;}void print(){std::cout << _year << "-" << _month << "-" << _date << std::endl;}private:int _year;int _month;int _date;
};int main()
{Date1 q1(2024 , 7 , 12);Date1 q5;q5 = q1;q5.print();return 0;
}

输出:

就如上图所示,我并没有写赋值运算符重载但是它却给我打印出和q1对象中的成员变量一样的值,所以我们可以得出结论编译器生成的默认赋值运算符会直接逐字节拷贝内置类型成员变量的值。俗称浅拷贝。

自定义类型:

代码演示:


//默认赋值运算符重载(自定义类型)
class Date2
{
public:// 赋值运算符重载Date2& operator=(const Date2& d){if (this != &d) { // 自我赋值检查_a = d._a;}return *this;}private:int _a = 10;
};class Date3
{
public:// 默认构造函数Date3(int year = 2005, int month = 5, int date = 25){this->_year = year;this->_month = month;this->date = date;}void print(){std::cout << _year << "-" << _month << "-" << _date << std::endl;}private:int _year;int _month;int _date;Date2 c; // 包含 Date2 类型的成员变量
};int main()
{Date3 q1(2024, 7, 12);Date3 q5;q5 = q1; // 使用编译器生成的默认赋值运算符q5.print();return 0;
}

输出:

如图所示编译器生成的默认赋值运算符会调用自定义类型的赋值运算符重载。

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

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

相关文章

安全防御:防火墙基本模块

目录 一、接口 1.1 物理接口 1.2 虚拟接口 二、区域 三、模式 3.1 路由模式 3.2 透明模式 3.3 旁路检测模式 3.4 混合模式 四、安全策略 五、防火墙的状态检测和会话表技术 一、接口 1.1 物理接口 三层口 --- 可以配置IP地址的接口 二层口&#xff1a; 普通二层…

车载终端_RTK定位|4路摄像头|驾驶辅助系统ADAS定制方案

现代车辆管理行业的发展趋势逐渐向智能化和高效化方向发展&#xff0c;车载终端成为关键的工具之一。在这个背景下&#xff0c;一款特别为车队管理行业设计的车载终端应运而生。该车载终端采用8寸多点触控电容屏&#xff0c;搭载联发科四核处理器&#xff0c;主频2.0GHz&#x…

如何安装node.js

Node.js Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境。 主要特点和优势&#xff1a; 非阻塞 I/O 和事件驱动&#xff1a;能够高效处理大量并发连接&#xff0c;非常适合构建高并发的网络应用&#xff0c;如 Web 服务器、实时聊天应用等。 例如&#xff0c;在…

网络安全——防御(防火墙)带宽以及双机热备实验

12&#xff0c;对现有网络进行改造升级&#xff0c;将当个防火墙组网改成双机热备的组网形式&#xff0c;做负载分担模式&#xff0c;游客区和DMZ区走FW3&#xff0c;生产区和办公区的流量走FW1 13&#xff0c;办公区上网用户限制流量不超过100M&#xff0c;其中销售部人员在其…

排序相关算法--3.选择排序

之前涉及的堆排序就是选择排序的一种&#xff0c;先进行选择。 基本选择排序&#xff1a; 最简单&#xff0c;也是最没用的排序算法&#xff0c;时间复杂度高并且还是不稳定的排序方法&#xff0c;项目中很少会用。 过程&#xff1a; 在一个长度为 N 的无序数组中&#xff0c;…

智慧公厕系统助力城市卫生管理

在当今快速发展的城市环境中&#xff0c;城市卫生管理面临着诸多挑战。其中&#xff0c;公共厕所的管理一直是一个重要但又常被忽视的环节。然而&#xff0c;随着科技的不断进步&#xff0c;智慧公厕系统的出现为城市卫生管理带来了全新的解决方案&#xff0c;成为提升城市品质…

OrangePi AIpro 浅上手

OrangePi AIpro 浅上手 OrangePi AIpro 介绍开发版介绍硬件规格顶层视图和底层视图接口详情图 玩转 OrangePi AIPro烧录镜像串口调试连接 WiFissh 连接配置下载源 使用感受优点&#xff1a;缺点或需注意的点&#xff1a; OrangePi AIpro 介绍 开发版介绍 OrangePi AIpro是香橙…

【大语言模型】私有化搭建-企业知识库-知识问答系统

下面是我关于大语言模型学习的一点记录 目录 人工智能学习路线 MaxKB 系统(基于大语言模型的知识问答系统) 部署开源大语言模型LLM 1.CPU模式(没有好的GPU&#xff0c;算力和效果较差) 2.GPU模式&#xff08;需要有NVIDIA显卡支持&#xff09; Ollama网络配置 Ollama前…

【问卷系统】TDucKX更新速览

TDuck是一款在线表单问卷收集工具&#xff0c;开源地址&#xff1a;https://gitee.com/TDuckApp一款免费的表单问卷系统&#xff1b;可快速创建问卷或业务表单&#xff0c;采用无代码理念支持开发自定义组件。采用SpringBootVueElementUI技术栈&#xff0c;功能强大界面清新&am…

Catena-x标准解读:CX-0007 Minimal Data Provider Service Offering v1.0.2 最小数据提供商服务产品

为了更好地理解&#xff0c;最小数据提供者服务也将被称为“上传工具”。 对于数据供应工具来说&#xff0c;数据主权的概念尤为重要。数据主权是Catena-X网络的核心价值观之一。每个参与者都应该尽可能多地控制自己的数据。这包括 他总是确切地知道他在与谁交换数据。参与者…

软件测试面试200问(全)

1、B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行&#xff0c;可以实现跨平台&#xff0c;客户端零维护&#xff0c;维护成本低&#xff0c;但是个性化能力低&#xff0c;响应速度较慢 C/S响应速度快&#xff0c;安全性强&#xff0c;一般应用于局域网中&#xff0…

【matlab】智能优化算法优化BP神经网络

目录 引言 一、BP神经网络简介 二、智能优化算法概述 三、智能优化算法优化BP神经网络的方法 四、蜣螂优化算法案例 1、算法来源 2、算法描述 3、算法性能 结果仿真 代码实现 引言 智能优化算法优化BP神经网络是一个重要的研究领域&#xff0c;旨在通过智能算法提高…

变量筛选—特征包含信息量

在变量筛选中,通过衡量特征所包含信息量大小,决定是否删除特征,常用的指标有单一值占比、缺失值占比和方差值大小。单一值或缺失值占比越高,表示特征包含信息量越少,不同公司设置不同阈值,一般单一值、缺失值占比高于95%,建议删除。方差值越小,代表特征包含信息量越小。…

入职前回顾一下git-01

git安装 Linux上安装git 在linux上建议用二进制的方式来安装git&#xff0c;可以使用发行版包含的基础软件包管理工具来安装。 红帽系 sudo yum install gitDebian系 sudo apt install gitWindows上安装git 去官网下载和操作系统位数相同的安装包.或者可以直接安装GitHub…

[图解]SysML和EA建模住宅安全系统-14-黑盒系统规约

1 00:00:02,320 --> 00:00:07,610 接下来&#xff0c;我们看下一步指定黑盒系统需求 2 00:00:08,790 --> 00:00:10,490 就是说&#xff0c;把这个系统 3 00:00:11,880 --> 00:00:15,810 我们的目标系统&#xff0c;ESS&#xff0c;看成黑盒 4 00:00:18,030 --> …

Power Apps使用oData访问表数据并赋值前端

在使用OData查询语法通过Xrm.WebApi.retrieveMultipleRecords方法过滤数据时&#xff0c;你可以指定一个OData $filter 参数来限制返回的记录集。 以下是一个使用Xrm.WebApi.retrieveMultipleRecords方法成功的例子&#xff0c;它使用了OData $filter 参数来查询实体的记录&am…

最新盘点!2024年最值得了解的24款项目管理软件

一、企业该如何选择一款项目管理工具&#xff1f;选择项目管理工具时需要考虑哪些因素&#xff1f; 在选择和对比项目管理工具时&#xff0c;可以通过加权方式进行对比和评估。参考以下模板&#xff0c;可以把自己关注的项目管理工具&#xff0c;进行表格对比&#xff0c;选中…

企业智能制造赋能的环境条件为什么重要?需要准备什么样的环境?

在全球制造业不断演进的今天&#xff0c;智能制造已经成为推动行业创新和转型的关键力量。它不仅代表了技术的革新&#xff0c;更是企业管理模式和运营思路的全面升级。然而&#xff0c;智能制造的落地实施并非一蹴而就&#xff0c;它需要企业在环境条件上做好充分的准备&#…

Pycharm与Gitlab交互

环境准备 1、下载配置好本地Git 2、配置Pycharm上的Git 3、gitlab账号 Gitlab配置 Gitlab配置中文 账号》设置》偏好设置》简体中文 创建项目 命令行操作 打开项目会展示以下步骤 在pycharm克隆gitlab的项目 通过菜单栏 1、在PyCharm的顶部菜单栏中&#xff0c;选择“V…

本地部署,Flash Diffusion: 加速条件扩散模型实现快速图像生成

目录 引言 技术背景 Flash Diffusion 的架构与原理 Flash Diffusion 的主要特点 本地部署 运行结果 实验结果与分析 应用实例 结论 GitHub - gojasper/flash-diffusion: Official implementation of ⚡ Flash Diffusion ⚡: Accelerating Any Conditional Diffusion M…