C++入门系列-赋值运算符重载

🌈个人主页:羽晨同学 

💫个人格言:“成为自己未来的主人~”  

赋值运算符重载

运算符重载

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

 函数名字为:关键字operator后面接需要重载的运算符符号。

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

注意:

  • 不能通过连接其他符号来创建新的操作符,比如operator@,这个其实完全没意义。
  • 重载操作符必须有一个类类型参数,这个就证明了重载操作符是针对自定义类型的,不可能针对内置类型。
  • 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不能改变其含义。
  • 作为类成员函数重载时,其形参看起来比操作数少一,因为有一个隐藏的this指针。
  • .*   ::  sizeof  ?:   .这五个运算符是不能重载的。

接下来我们先来讲讲这五个不能重载的运算符中的第一个。这个运算符是极其少见的。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class OB
{
public:
	void func()
	{
		cout << "void func()" << endl;
	}
};
typedef void(OB::* PtrFunc)();

int main()
{
	PtrFunc fp = &OB::func;//成员函数取地址要加一个&,普通函数函数名就是地址
	
	OB temp;
	
	(temp.*fp)();


	return 0;
}

其实.*的作用是什么呢,我们可以通过这段代码看到,.*的作用就是帮助我们调用成员函数的指针。

 接下来,我们就回到了operator关键字的作用,这个关键字可以极大的提高代码的可读性,我们来看下面的代码。

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	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;
}
void Test()
{
	Date d1(2018,9.26);
	Date d2(2018, 9, 27);
	cout << (d1 == d2) << endl;
}

这段代码是operator的全局调用,我们会看到如果全局调用的话会存在一个问题,那就是成员变量是私有的。我们无法保证封装性。

这里的解决办法有三种,

  1.  提供这些成员的get和set
  2. 友元 
  3. 重载为成员函数

我们一般使用的就是第三种。重载为成员函数

什么意思呢?我们来看下面的这段代码

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool Func(const Date& d)
	{
		return this->_year == d._year
			&& this->_month == d._month
			&& this->_day == d._day;
	}
	bool operator==(const Date& d)
	{
		return this->_year == d._year
			&& this->_month == d._month
			&& this->_day == d._day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d3(2024, 4, 14);
	Date d4(2024, 4, 15);

	cout << d3.operator==(d4) << endl;
	cout << (d3 == d4) << endl;
	return 0;
}

 懂了吗,我们将重载函数放到成员函数里面,就避免了权限不够的问题。

赋值运算符重载

赋值运算符重载格式

  • 参数类型:const T&,传递引用可以提高传参效率。
  • 返回值类型: T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续复制
  • 检测是否自己给自己复制
  • 返回*this,要复合连续赋值的含义。
#include<iostream>
using namespace std;

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		cout << "	Date(const Date& d)" << endl;

		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	~Date()
	{
		cout << "~Date()" << endl;
		_year = -1;
		_month = -1;
		_day = -1;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2024, 4, 14);
	Date d2(d1);
	Date d3 = d1;
	return 0;
}

 2.赋值运算符只能重载成类的成员函数不能重载成全局函数

这个怎么理解呢?其实重载成类的成员函数和重载成全局函数有一个很大的不同点,就是成员函数还有一个潜在的this指针,而全局函数是没有这个东西,所以,如果要重载为全局函数的话,我们就需要给两个参数。

class Date
{
public:
	Date(int year = 1949, int month = 10, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

Date& operator=(Date& left, const Date& right)
{
	if (&left != &right)
	{
		left._year = right._year;
		left._month = right._month;
		left._day = right._day;
	}
	return left;
}

我们发现这个代码是会报错的, 原因是由于赋值运算符如果不显示实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中编译器自己生成的默认赋值运算符重载冲突了,故赋值运算符重载只能是类的成员函数。

用户没有显示实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝,注意:内置类型成员变量是直接赋值的,而自定义类型变量是需要调用对应类的赋值运算符重载完成赋值。

class Date
{
public:

	Date(int year = 2024, int month = 3, int day = 4)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _month;
	int _day;
	int _year;
};
int main()
{
	Date d1(2024, 5, 15);
	Date d2;
	d2 = d1;

	return 0;
}
#include<iostream>
using namespace std;
class Time
{
public:

private:
	int _hour = 1;
	int _second = 1;
	int _minute = 1;
};
class Date
{
public:
	void Print()
	{
		cout << "class Time" << endl;
	}
	Date(int year = 2024, int month = 3, int day = 4)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _month;
	int _day;
	int _year;
	Time _t;
};
int main()
{
	Date d1(2024, 5, 15);
	Date d2;
	d2 = d1;
	d1.Print();
	d2.Print();

	return 0;
}

 

通过这个结果,我们可以很明显的得出上面的结论。

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

评价决策类-层次分析法

师从江北 问题引出 归一化处理&#xff1a;指标的数组[a b c]归一化处理得到[a/(abc),b/(abc),c/(abc)] 因为每个指标的重要性不同&#xff0c;所以要加上一个权重 如何科学的确定权重&#xff0c;就要用到层次分析法&#xff08;AHP&#xff09; 模型原理 建立递阶层次结构模…

百度云防护如何开启CC攻击防护

百度云防护的最重要的功能是可以CC攻击防护&#xff0c;针对CC攻击&#xff0c;百度云防护有被动的CC攻击拦截规则&#xff0c;也有主动自定义访问策略拦截。 今天百度云来教大家如何开启百度云防护的CC攻击防御功能。 1.进入防护模板功能-创建模板 2.开启CC攻击防御功能&…

ubuntu20.04 ROS 环境下使用速腾80线激光雷达

1.相关系统环境 系统版本:ubuntu 20.04 ROS版本&#xff1a;ROS1 - noetic 激光雷达型号&#xff1a;RoboSense Ruby &#xff08;更新于2024.5.14&#xff09; 2.网口配置&#xff1a; 将PC/工控机的网口配置为&#xff1a; ipv4&#xff0c;方式设置为手动 ip地址、掩码以…

半小时搞懂STM32知识点——UART

1.UART 1.1为什么要使用UART这种协议?介绍一下UART及其特点 成本低&#xff0c;硬件简单&#xff0c;数据格式灵活&#xff1b; 低速全双工异步串行通信 1.2 UART数据帧格式&#xff1f; 起始位&#xff08;1&#xff09;&#xff0b;数据位&#xff08;5-8&#xff09; 校验位…

保研机试之【execve函数】

execve 参考&#xff1a;fork&#xff08;&#xff09;函数两次返回_fork是如何返回两次的-CSDN博客 setjmp/longjmp 还有E&#xff1a;

解决kali Linux2024无法获取动态IPv4地址(DHCP)解决方案

用root用户启动终端 进入根目录&#xff0c;选择配置文件 cd到根目录下/../etc/network找到interfaces文件 编辑interfaces文件 vi interfaces&#xff0c;编辑interfaces文件 输入如下命令 打开虚拟网络编辑器 选择虚拟机选项卡&#xff0c;编辑&#xff0c;打开虚拟网络编…

数据结构——二叉树知识点详解!

引言&#xff1a;本篇博客将详细介绍到数据结构中的又一位大将——二叉树。它也是我们目前学到的第一个非线性的数据结构。并且本章将学到的概念居多&#xff0c;希望大家可以理解并牢记。 更多有关C语言和数据结构知识详解可前往个人主页&#xff1a;计信猫 目录 一&#xff0…

C++语法|对象的浅拷贝和深拷贝

背景&#xff1a; 我们手写一个顺序栈&#xff0c;展开接下来的实验&#xff1a; ⭐️ this指针指向的是类在内存中的起始位置 class SeqStack { public:SqeStack(int size 10) {cout << this << "SeqStack()" << endl;pstack_ new int[size_];t…

Gemini 5.14日更新 - 推出Gemini Advance服务

收到Gemini Advance试用邀请 今天和往常一样&#xff0c;打开Gemini&#xff0c;惊喜的发现右小角一行小字&#xff1a;试用Gemini Advance。好家伙&#xff0c;OpenAI 刚推出ChatGPT 4o&#xff0c;Google立马推出Gemini Advance&#xff0c;说明国外高科技企业也是很拼的。 …

STC8增强型单片机开发【热敏电阻】

目录 一、引言 二、热敏电阻概述 三、STC8增强型单片机简介 四、基于STC8单片机的热敏电阻测温系统 五、热敏电阻测温系统的优化与扩展 提高测量精度 扩展系统功能 六、 温度计算步骤 通过ADC采样计算出热敏电阻位置的电压 通过欧姆定律计算热敏电阻的阻值 通过阻值…

【Linux】常用指令、热键与权限管理

一、常用指令 &#xff08;1&#xff09;ls 功能&#xff1a;列出指定目录下的所有子目录与文件 用法&#xff1a;ls &#xff08;选项&#xff09; &#xff08;目录或文件名&#xff09; 常用选项&#xff1a; -a&#xff1a;列出目录下的所有文件&#xff0c;包括隐藏…

fastjson1.2.68对于文件操作的分析最全

fastjson1.2.68对于文件操作的分析 前言分析复制文件写入文件读取文件分析poc拓宽场景极限环境poc优化修改再次优化poc的分析 前言 这次分析也是分析了很久&#xff0c;因为每个链子都是自己去跟着分析了的&#xff0c;然后主要是去学习了一下怎么去挖链子 分析 前面漏洞复现…

TypeScript中的泛型(Generics)

TypeScript中的泛型&#xff08;Generics&#xff09; 在前面的几篇文章中&#xff0c;我们了解了TypeScript的类、接口和基本的数据类型系统。本文将重点介绍TypeScript中的泛型&#xff0c;这是一种强大的工具&#xff0c;它允许我们创建可重用的组件&#xff0c;同时保持类…

【Java学习笔记10 Java Web 应用——JSP

JSP(Java Script Pages)技术是一种网站开发技术&#xff0c;可以让Web开发人员快速、高效的开发出易于维护的动态网页。使用JSP技术开发的Web应用程序具有跨平台性&#xff0c;不需要修改程序&#xff0c;发布后即可在Windows、Linux等不同的操作系统中运行。 10.1 JSP技术概述…

申请免费通配符证书

通配符证书是一种 SSL/TLS 证书&#xff0c;可用于保护多个域&#xff08;主机&#xff09;&#xff0c;由域名字段中的通配符 (*) 指示。这种证书主要用于具有许多子域的组织。通配符证书对主域及其所有次级子域有效。 通配符证书和多域名证书的区别&#xff1a; 要注意的是…

webpack优化构建速度示例-合理配置loader的include exclude:

实际上&#xff0c;babel-loader 在 Webpack 配置中默认并不包含 exclude 和 include 选项的默认值&#xff0c;通常&#xff0c;为了优化构建性能&#xff0c;开发者会显式地设置 exclude 和 include 选项&#xff0c;以便 babel-loader 只处理必要的文件。 src/index.js impo…

Zookeeper and RPC dubbo

javaguide zookeeper面试题 Zookeeper 啥是Zookeeper干啥的 ZooKeeper 可以被用作注册中心、分布式锁&#xff1b; ZooKeeper 是 Hadoop 生态系统的一员&#xff1b; 构建 ZooKeeper 集群的时候&#xff0c;使用的服务器最好是奇数台。 启动ZK 下载安装解压 不过多赘述 我的…

Spring:了解@Import注解的三种用法

一、前言 在 Spring 框架中&#xff0c;Import 注解用于导入配置类&#xff0c;使得你可以在一个配置类中引入另一个或多个配置类&#xff0c;从而实现配置的模块化。这对于组织大型应用程序的配置非常有用&#xff0c;因为它允许你将配置分散到多个类中&#xff0c;然后再将它…

RAW转换和图像编辑工具:Capture One 23 Pro (win/mac)中文专业版

Capture One 23是一款功能强大的桌面版照片编辑软件&#xff0c;由丹麦PHASE ONE飞思数码公司开发。 以下是该软件的一些主要特点&#xff1a; 强大的RAW处理功能&#xff1a;Capture One 23支持多种品牌的相机和镜头&#xff0c;提供了丰富的RAW处理工具&#xff0c;包括曝光、…

RALL-E: Robust Codec Language Modeling with Chain-of-Thought Prompting for TTS

demo pageDetai Xin&#xff0c; tanxu微软 & 东大 & 浙大 abstract 使用CoT的思路&#xff0c;和Valle的框架&#xff0c;先实现LLM预测音素级别pitch/duration&#xff0c;然后预测speech token。 methods Prosody tokens as chain-of-thought prompts 和Valle一…