C/C++语言基础--C++运算符重载以及其重载限制

news2024/9/27 23:03:39

本专栏目的

  • 更新C/C++的基础语法,包括C++的一些新特性

前言

  • 通过前面几节,我们介绍了C++的类与对象、构造与析构函数、拷贝、成员变量、特殊变量等相关知识,这一篇将详细介绍了C++的运算符重载,我感觉这是C++的一个很伟大的发明,让自定义类型有了和普通数据一样进行运算;
  • C语言后面也会继续更新知识点,如内联汇编;
  • 本人现在正在写一个C语言的图书管理系统,1000多行代码,包含之前所学的所有知识点,包括链表和顺序表等数据结构,请大家耐心等待!!预计国庆前写完更新。

文章目录

    • 什么是运算符重载
    • 运算符重载的意义
    • 运算符重载限制
      • 可以重载的运算符
      • 不能重载的运算符
    • 运算符重载规则
    • 运算符重载方法
      • 两种重载方法
      • 注意点
    • 单目运算符重载
      • 单目运算符
      • 重载自增、自减法
    • 双目运算符重载
    • 类型转换重载

什么是运算符重载

运算符重载,就是赋予运算符新的含义。它是重载系统内部运算符的函数,是实现类静态多态性的方式之一。它本质上是函数重载

让我们来看一下这个需求,需要对比A1同学和A2同学年龄的大小:

// 假设都属于学生类
Student A1("wy", 18), A2("Wq", 19);
// 想要对比谁的年龄大,试想一下,能不能像正常比较大小那样直接比较呢?
cout << A1 < A2 << endl;

答案当然是可以的,这个就是我们这节课要学习的**“运算符重载”**,这样进行重载后,类更像是一种自定义数据类型。

实际上,我们已经在不知不觉之中使用了运算符重载。列如:

  • 我们习惯使用的对整数,浮点数运用+、-、*、/,其实计算机对整数和浮点数的操作过程是不一样的,这个主要是整数和浮点数的编码规则不同(详细请看《深入了解计算机系统》),但由于C++已经对运算符进行了重载,所以才能都适用。

  • 又如<<本来是左移运算符,但在输出操作中,与cout搭配,当作输出流运算符了

运算符重载的意义

我们平常常见的算术运算符、逻辑运算符等运算符都是系统库函数里面已经存在的,所以运算符可以直接用于我们常用的数据类型。然而对于我们自定义的类实例化的对象,系统没有与之相关的运算符可以操作,但是为了使我们编写程序时更加便捷,C++提供了一种方式——运算符重载,来满足我们对于类对象进行的操作。

总的来说就是,C++的数据是对类的抽象,运算符重载就可以让我们自定义类型可以像平常数据类型一样进行运算

运算符重载限制

C++中绝大部分的运算符允许重载,少部分不允许重载,详细描述如下(忘了现查即可):

可以重载的运算符

  • 算术运算符:+ - * / %
  • 自增、自减运算符:++ –
  • 位运算符:| & ~ ^ << >>
  • 逻辑运算符:|| && !
  • 关系运算符:== != < > <= >=
  • 赋值运算符:= += -= /= %= &= |= ^= <<= >>=
  • 单目运算符:+ - * &
  • 动态内存分配:new delete new[] delete[]
  • 其他运算符:() -> , []

不能重载的运算符

  • . 成员访问运算符
  • :: 域运算符
  • .* ->* 成员指针访问运算符
  • szieof 长度运算符
  • ?: 条件运算符

运算符重载规则

  • 重载运算符函数可以对运算符作出新的解释﹐但原有基本语义不变:
    • 不改变运算符的优先级
    • 不改变运算符的结合性
    • 不改变运算符所需要的操作数
    • 不能创建新的运算符
  • 语法:

在这里插入图片描述

  • 一个运算符被重载后,原有意义没有失去,只是定义了相对一特定类的一个新运算符。

举例,上面比较年龄的实现:

#include <iostream>

using namespace std;

class Student
{
public:
	Student(std::string name, int age)
		:m_name(name),
		m_age(age)
	{

	}

	bool operator<(const Student& other) 
	{
		return this->m_age < other.m_age;
	}

private:
	std::string m_name;
	int m_age;
};

int main()
{
	Student a1("w", 18), a2("y", 19);

	bool res = a1 < a2;

	cout << boolalpha <<  res << endl;

	// 输出结果: true

	return 0;
}

为什么直接一下操作输出呢?

cout << a1 < a2;

因为优先级的问题,<< 大于 < ,如果使用以上代码,则实际它运行的是:

(cout << a1) << a2;

而类是输出不了的,他不是标准类型,不能匹配,需要我们自定义内容,具体怎么操作,还需要往下学习。

运算符重载方法

两种重载方法

重载为成员函数全局(友元)函数(友员函数非必要不用)

// 实现字符串内容连接
MyObject operator+(const char* str)
{
    MyObject temp(size + strlen(str) + 1);
    strcpy(temp.c_str, c_str);  // 拷贝
    strcat(temp.c_str, str);  // 连接
}

两种形式的选择:

  • 左操作数(或者只有左操作数并且)本类的对象时,可选用成员函数形式。
MyObject& operator=(const MyObject& other);
MyObject& operator=(const char* str);
  • 左操作数不是本类的对象,必须采用非成员函数的形式,一般是友元函数

这一种情况一般用于输出对象,因为对象不是标准类型,他不能直接输出,那如果我想要执行一下操作就直接输出该学生信息呢?

Student a1("wy", 18);
cout << a1;

这个时候就可以用我们的运算符重载了,如下:

#include <iostream>

using namespace std;

class Student
{
	friend ostream& operator<<(ostream& out, const Student& other);
public:
	Student(std::string name, int age)
		:m_name(name),
		m_age(age)
	{

	}

	bool operator<(const Student& other) 
	{
		return this->m_age < other.m_age;
	}
private:
	std::string m_name;
	int m_age;
};

// 友员一般在类外实现,但是在类内中间实现也行
ostream& operator<<(ostream& out, const Student& other)
{
	out << "Name: " << other.m_name << ", Age: " << other.m_age << endl;
	return out;
}

int main()
{
	Student a1("w", 18), a2("y", 19);

	cout << a1;
    
    // 输出:Name: w, Age: 18

	return 0;
}

当然也可以重载输入:

friend istream& operator>>(istream& out, const Student& other);

注意点

一般单目运算符最好被重载为成员函数;双目运算符重载为友元函数

注意:有些运算符不能重载为友元函数,它们是:=,(),[]和->。

  • 具有可交换性的双目运算符最好两种形式都有(成员函数时适用左操作数为本类对象,友元函数时适用左操作数为其他类的对象),也就是需要重载两种运算符1
// 如下
"123" + zc;
zc + "123";  // 两种都需要重载

·

单目运算符重载

什么是单目,什么是双目呢?顾名思义,就是运算符的操作数的个数

  • 单目就是一个操作数,比如++,a++,操作数只有一个a,写成a++b是非法的。
  • 双目就是两个操作数,最熟悉的就是+,a+b,计算ab的和
  • 三目就是三个操作数,目前只有一个条件运算符,?运算符,比如a?b;c,当a的值为真时,结果是b,否则结果是c。

单目运算符

一些只需要一个操作数的运算符称为一元运算符(或单目运算符)。

重载自增、自减法

  1. 返回类型不同

  2. 形参不同

  3. 效率不同

    Student& operator++() 
    {
    	this->m_age += 1;
    	return* this;
    }
    
    Student operator++(int)
    {
    	Student temp = *this;
    	++* this;
    	return temp;
    }
    

双目运算符重载

一些需要两个操作数的运算符称为二元运算符(或双目运算符)

// 对年龄相加
int operator+(const Student& a1, const Student& a2)
{
    return a1.m_age + a2.m_age;
}

同样的道理,三目就是操作数为三个。

类型转换重载

类型重载就是没有返回值类型的,自动推断,如下一个例子:

//类型转换强转
//1.没有返回类型
operate int()
{
    return 
}

//
class Text
{
private:
    int m_a;
public:
    operator int()
    {
        return int(m_a);
    }
}

int main()
{
    Text a(99);
    int b = a;    //将对象赋值给一个变量
    rerurn 0;
}
  • 上面a(99)运算过程,a会在class找,找能赋值的运算符重载

注意: 与运算符 = 重载的区别, a = 99; 这样是 = 重载,将一个值赋值给对象 , 即左操作数不是本类对象

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

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

相关文章

[数据结构] 二叉树题目(一)

目录 一.翻转二叉树 1.1 题目 1.2 示例 1.3 分析 1.4 解决 ​编辑 二. 相同的树 2.1 题目 2.2 示例 2.3 分析 2.4 解决 三. 对称二叉树 3.1 题目 3.2 示例 3.3 分析 3.4 解决 一.翻转二叉树. - 力扣&#xff08;LeetCode&#xff09; 1.1 题目 1.2 示例 1.3 分…

猫头虎 分享已解决Bug: || Module not found: Can‘t resolve ‘react‘ 解决方案

&#x1f42f;猫头虎 分享已解决Bug&#xff1a; || Module not found: Cant resolve react 解决方案 摘要: 今天猫头虎带大家解决一个常见的前端问题&#xff0c;尤其是在 React 项目中&#xff0c;很多开发者在安装依赖包时&#xff0c;遇到过 Module not found: Cant resol…

基于大数据技术的颈椎病预防交流与数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Mybatis详细教程 (万字详解)

Mybatis 3.5.14 来自于B站‘天气预报’,一名宝藏up,跟着他可以培养起独立解决编程问题的能力&#xff01;&#xff01;&#xff01; 01.简介 1.1 官网 官方中文网: MyBatis中文网 中文网参考手册 1.2 概念 MyBatis 是一款优秀的持久层框架&#xff0c;支持自定义 SQL, 存储过…

《强化学习的数学原理》(2024春)_西湖大学赵世钰 Ch9 策略梯度方法 9.3.2 无折扣情形下的梯度推导

v3 链接 9.3.2 无折扣情形下的梯度推导 平均奖励 r ˉ π \bar r_\pi rˉπ​ 的定义对折扣和无折扣情况都有效。在折扣情况下的梯度是一个近似值&#xff0c;它在无折扣情况下的梯度更优雅。 因为 无折扣奖励和 E [ R t 1 R t 2 R t 3 ⋯ ∣ S t s ] {\mathbb E}[…

常见框架漏洞复现

1、Thinkphp5x远程命令执行及getshell 1、环境配置 靶场:vulhub/thinkphp/5-rce docker-compose up -d 2、漏洞利用 漏洞根本源于 thinkphp/library/think/Request.php 中method方法可以进行变量覆盖&#xff0c;通过覆盖类的核心属性filter导致rce&#xff0c;其攻击点较为…

C++的vector优化

1、C中的动态数组一般是特指vector类 2、vector需要优化的原因之一是当我们push_back元素到数组中时&#xff0c;如果原来分配给动态数组的内存不够用了&#xff0c;那么就会找一块更大的内存空间分配给数组&#xff0c;把旧的内容复制到新的内存中去&#xff0c;这就是导致程…

过流会导致并联电容损坏吗

在电子元器件领域&#xff0c;电容作为重要的储能元件&#xff0c;广泛应用于电路滤波、耦合、解耦等多种场合。然而&#xff0c;当电流超过其额定容量时&#xff0c;过流现象可能对电容造成严重的损坏&#xff0c;特别是在并联电容的应用场景下。这是什么原因呢&#xff1f;一…

考研数据结构——C语言实现归并排序

包含头文件&#xff1a;程序首先包含了标准输入输出库stdio.h&#xff0c;以便使用printf等函数进行输入输出操作。 定义数组和数组大小&#xff1a;定义了一个宏N&#xff0c;其值为5&#xff0c;表示数组q的长度。数组q被初始化为{5, 3, 8, 4, 2}&#xff0c;这是我们要排序…

高性能计算应用优化实践之WRF

WRF&#xff08;Weather Research Forecast&#xff09;模式是由美国国家大气研究中心&#xff08;NCAR&#xff09;、国家环境预报中心&#xff08;NCEP&#xff09;等机构自1997年起联合开发的新一代高分辨率中尺度天气研究预报模式&#xff0c;重点解决分辨率为1&#xff5e…

Android 热点分享二维码功能简单介绍

Android 热点分享二维码 文章目录 Android 热点分享二维码一、前言二、热点二维码1、热点分享的字符串2、代码中热点字符串拼接和设置示例3、一个图片示例 三、其他1、Android 热点分享二维码小结2、Android11 设置默认热点名称和热点密码、密码长度 一、前言 比较新的Android…

智慧教育新篇章:AI如何改变英语学习方式

斯坦福大学最新发布的《2024年人工智能指数报告》指出&#xff0c;2023年全球范围内新推出的大型语言模型数量实现了翻倍增长。人工智能越来越多的被公众使用&#xff0c;并对生产力提升和就业市场产生了深远影响。作为发展新质生产力的重要引擎&#xff0c;人工智能正逐渐渗透…

React表单:formik、final-form和react-hook-form

表单无处不在&#xff0c;它是每个网站的必备部分。在用React构建web应用时&#xff0c;处理表单是不可避免的。 你可以选择自己的方式来处理&#xff0c;或者选择社区中现成的库。然而&#xff0c;当你选择一个第三方库时&#xff0c;你会立即面临一个问题&#xff1a;有太多的…

一文彻底掌握inout双向端口

inout端口信号在FPGA中应用还是很广泛的&#xff0c;特别是一些总线通信、数据交互的场景&#xff0c;比如i2c、spi等等。 一、inout的基本概念 Inout 端口的实现基础是三态门。 三态门具有三种输出状态&#xff0c;即高电平、低电平以及高阻态&#xff08;Z&#xff09;。 …

win11下 keil报错Cannot load driver ‘D:\Keil_v5\ARM\Segger\JL2CM3.dll‘

现象 更新系统后&#xff08;win10->win11&#xff09;,发现Keil编译或者调试居然报错了&#xff1a; 但是在该路径下&#xff0c;还是能找到JL2CM3.dll这个文件的 解决方法 进入系统环境变量设置 在Path添加环境变量JL2CM3.dll所在路径&#xff0c;我这里就是‘D:\Keil_v…

中国新媒体联盟与中运律师事务所 建立战略合作伙伴关系

2024年9月27日&#xff0c;中国新媒体联盟与中运律师事务所举行战略合作协议签字仪式。中国新媒体联盟主任兼中国社会新闻网主编、中法新闻法制网运营中心主任左新发&#xff0c;中运律师事务所高级顾问刘学伟代表双方单位签字。 中国新媒体联盟是由央视微电影中文频道联合多家…

jupyter使用pytorch

1、激活环境 以下所有命令都在Anaconda Prompt中操作。 conda activate 环境名称我的环境名称是myenv 如果不知道自己的pytorch配在哪个环境&#xff0c;就用下面方法挨个试。 2、安装jupyter 1、安装 pip install jupyter2、如果已经安装&#xff0c;检查jupyter是否已…

第五部分:5---三张信号表,信号表的系统调用

目录 信号的递达、未决、阻塞&#xff1a; 进程维护的三张信号表&#xff1a; 普通信号与实时信号的记录&#xff1a; 信号结构的系统调用&#xff1a; bolck表的系统调用&#xff1a; 实例&#xff1a;设置屏蔽信号集中的所有信号都频闭 pending表读取&#xff1a; 信号…

第一本RAG书籍《大模型RAG实战》出版!

随着ChatGPT的爆火&#xff0c;推动了新一轮的AI技术进步。但大模型自身存在幻觉、知识更新难等问题&#xff0c;阻碍了其直接进行落地应用。RAG&#xff08;Retrieval-Augmented Generation&#xff09;技术将LLM与文本信息检索相结合&#xff0c;解决了在一些场景下模型知识不…

数字人直播违规原因究竟是什么?哪些技术可以解决?

随着人工智能时代的来临&#xff0c;以数字人直播为代表的技术应用逐渐被各大中小型企业引进&#xff0c;并成为了它们在直播板块降本增效的利器。不过&#xff0c;从目前的应用情况来看&#xff0c;不少企业都在使用数字人无人直播的过程中遭遇了违规封号的问题。在此背景下&a…