C嘎嘎的运算符重载基础教程以及遵守规则【文末赠书三本】

news2024/11/25 2:46:54

博主名字:阿玥的小东东

大家一起共进步!

目录

基础概念

优先级和结合性

不会改变用法

在全局范围内重载运算符

小结

本期送书:盼了一年的Core Java最新版卷Ⅱ,终于上市了


基础概念

运算符重载是通过函数重载实现的,概念上大家都很容易理解,这节我们来说一下运算符重载的注意事项。

1) 并不是所有的运算符都可以重载。能够重载的运算符包括:
+  -  *  /  %  ^  &  |  ~  !  =  <  >  +=  -=  *=  /=  %=  ^=  &=  |=  <<  >>  <<=  >>=  ==  !=  <=  >=  &&  ||  ++  --  ,  ->*  ->  ()  []  new  new[]  delete  delete[]

上述运算符中,[]是下标运算符,()是函数调用运算符。自增自减运算符的前置和后置形式都可以重载。长度运算符sizeof、条件运算符: ?、成员选择符.和域解析运算符::不能被重载。

优先级和结合性



2) 重载不能改变运算符的优先级和结合性。假设上一节的 complex 类中重载了+号和*号,并且 c1、c2、c3、c4 都是 complex 类的对象,那么下面的语句:

c4 = c1 + c2 * c3;

等价于:

c4 = c1 + ( c2 * c3 );

乘法的优先级仍然高于加法,并且它们仍然是二元运算符。

不会改变用法



3) 重载不会改变运算符的用法,原有有几个操作数、操作数在左边还是在右边,这些都不会改变。例如~号右边只有一个操作数,+号总是出现在两个操作数之间,重载后也必须如此。

4) 运算符重载函数不能有默认的参数,否则就改变了运算符操作数的个数,这显然是错误的。

5) 运算符重载函数既可以作为类的成员函数,也可以作为全局函数。

将运算符重载函数作为类的成员函数时,二元运算符的参数只有一个,一元运算符不需要参数。之所以少一个参数,是因为这个参数是隐含的。

例如,上节的 complex 类中重载了加法运算符:

complex operator+(const complex & A) const;

当执行:

c3 = c1 + c2;

会被转换为:

c3 = c1.operator+(c2);

通过 this 指针隐式的访问 c1 的成员变量。

将运算符重载函数作为全局函数时,二元操作符就需要两个参数,一元操作符需要一个参数,而且其中必须有一个参数是对象,好让编译器区分这是程序员自定义的运算符,防止程序员修改用于内置类型的运算符的性质。

例如,下面这样是不对的:

 
  1. int operator + (int a,int b){
  2. return (a-b);
  3. }

+号原来是对两个数相加,现在企图通过重载使它的作用改为两个数相减, 如果允许这样重载的话,那么表达式4+3的结果是 7 还是 1 呢?显然,这是绝对禁止的。

如果有两个参数,这两个参数可以都是对象,也可以一个是对象,一个是C ++内置类型的数据,例如:

 
  1. complex operator+(int a, complex &c){
  2. return complex(a+c.real, c.imag);
  3. }

它的作用是使一个整数和一个复数相加。

另外,将运算符重载函数作为全局函数时,一般都需要在类中将该函数声明为友元函数。原因很简单,该函数大部分情况下都需要使用类的 private 成员。

上节的最后一个例子中,我们在全局范围内重载了+号,并在 complex 类中将运算符重载函数声明为友元函数,因为该函数使用到了 complex 类的 m_real 和 m_imag 两个成员变量,它们都是 private 属性的,默认不能在类的外部访问。

6) 箭头运算符->、下标运算符[ ]、函数调用运算符( )、赋值运算符=只能以成员函数的形式重载。

所谓重载,就是赋予新的含义。函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作。运算符重载(Operator Overloading)也是一个道理,同一个运算符可以有不同的功能。

实际上,我们已经在不知不觉中使用了运算符重载。例如,+号可以对不同类型(int、float 等)的数据进行加法操作;<<既是位移运算符,又可以配合 cout 向控制台输出数据。C++本身已经对这些运算符进行了重载。

C++ 也允许程序员自己重载运算符,这给我们带来了很大的便利。

下面的代码定义了一个复数类,通过运算符重载,可以用+号实现复数的加法运算:

 
#include <iostream>
using namespace std;

class complex{
public:
complex();
complex(double real, double imag);
public:
//声明运算符重载
complex operator+(const complex &A) const;
void display() const;
private:
double m_real; //实部
double m_imag; //虚部
};

complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }

//实现运算符重载
complex complex::operator+(const complex &A) const{
complex B;
B.m_real = this->m_real + A.m_real;
B.m_imag = this->m_imag + A.m_imag;
return B;
}

void complex::display() const{
cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}

int main(){
complex c1(4.3, 5.8);
complex c2(2.4, 3.7);
complex c3;
c3 = c1 + c2;
c3.display();

return 0;
}

运行结果:
6.7 + 9.5i

本例中义了一个复数类 complex,m_real 表示实部,m_imag 表示虚部,第 10 行声明了运算符重载,第 21 行进行了实现(定义)。认真观察这两行代码,可以发现运算符重载的形式与函数非常类似。

运算符重载其实就是定义一个函数,在函数体内实现想要的功能,当用到该运算符时,编译器会自动调用这个函数。也就是说,运算符重载是通过函数实现的,它本质上是函数重载。

运算符重载的格式为:

返回值类型 operator 运算符名称 (形参表列){
    //TODO:
}

operator是关键字,专门用于定义重载运算符的函数。我们可以将operator 运算符名称这一部分看做函数名,对于上面的代码,函数名就是operator+

运算符重载函数除了函数名有特定的格式,其它地方和普通函数并没有区别。

上面的例子中,我们在 complex 类中重载了运算符+,该重载只对 complex 对象有效。当执行c3 = c1 + c2;语句时,编译器检测到+号左边(+号具有左结合性,所以先检测左边)是一个 complex 对象,就会调用成员函数operator+(),也就是转换为下面的形式:

c3 = c1.operator+(c2);

c1 是要调用函数的对象,c2 是函数的实参。

上面的运算符重载还可以有更加简练的定义形式:

 
complex complex::operator+(const complex &A)const{
return complex(this->m_real + A.m_real, this->m_imag + A.m_imag);
}

return 语句中的complex(this->m_real + A.m_real, this->m_imag + A.m_imag)会创建一个临时对象,这个对象没有名称,是一个匿名对象。在创建临时对象过程中调用构造函数,return 语句将该临时对象作为函数返回值。

在全局范围内重载运算符

运算符重载函数不仅可以作为类的成员函数,还可以作为全局函数。更改上面的代码,在全局范围内重载+,实现复数的加法运算:

 
#include <iostream>
using namespace std;

class complex{
public:
complex();
complex(double real, double imag);
public:
void display() const;
//声明为友元函数
friend complex operator+(const complex &A, const complex &B);
private:
double m_real;
double m_imag;
};

complex operator+(const complex &A, const complex &B);

complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }
void complex::display() const{
cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}

//在全局范围内重载+
complex operator+(const complex &A, const complex &B){
complex C;
C.m_real = A.m_real + B.m_real;
C.m_imag = A.m_imag + B.m_imag;
return C;
}

int main(){
complex c1(4.3, 5.8);
complex c2(2.4, 3.7);
complex c3;
c3 = c1 + c2;
c3.display();

return 0;
}

运算符重载函数不是 complex 类的成员函数,但是却用到了 complex 类的 private 成员变量,所以必须在 complex 类中将该函数声明为友元函数。

当执行c3 = c1 + c2;语句时,编译器检测到+号两边都是 complex 对象,就会转换为类似下面的函数调用:

c3 = operator+(c1, c2);

小结

虽然运算符重载所实现的功能完全可以用函数替代,但运算符重载使得程序的书写更加人性化,易于阅读。运算符被重载后,原有的功能仍然保留,没有丧失或改变。通过运算符重载,扩大了C++已有运算符的功能,使之能用于对象。

本期送书:盼了一年的Core Java最新版卷Ⅱ,终于上市了

本期送书:本期赠书三本:《Java核心技术·卷Ⅱ 高级特性(原书第12版》

获得方式:

高质量的评论+赞数的前两名各获得一本!

评论区随机挑选一位好兄弟送书一本!

开奖时间:5月10日晚8点

Java诞生28年来,这本享誉全球的 Java 经典著作《Core Java》一路伴随着 Java 的成长,得到了百万 Java 开发者的青睐,成为一本畅销不衰的Java经典图书,影响了几代技术人。

最新版中文版《Java核心技术(原书第12版)经全面修订,以涵盖Java 17的新特性。新版延续之前版本的优良传统,用数百个实际的工程案例,全面系统地讲解了Java语言的核心概念、语法、 重要特性、 开发方法。

着力让读者在充分理解Java语言和Java类库的基础上,灵活应用Java提供的高级特性,具体包括面向对象程序设计、反射与代理、接口与内部类、异常处理、泛型程序设计、集合框架、事件监听器模型、图形用户界面设计和并发。

Core Java最新版卷Ⅱ现已上市

Java 之父先前也说,开发者应尽快弃用 JDK 8,可以选择 JDK 17 长期支持版本。针对 Java 17 新特性全面更新的《Core Java》最新版第12版中文版《Java核心技术·卷Ⅰ开发基础(原书第12版)》自去年5月上市以来,一经发布就引起了轰动,得到数万读者的高度关注 ,大家纷纷留言都在盼望卷Ⅱ的上市!

对经验丰富的程序员来说,如果希望为实际应用编写出健壮的代码,那么《Java核心技术》绝对是一本业内领先的、言简意赅的宝典。如今,它终于来啦!《Java核心技术·卷Ⅱ 高级特性(原书第12版》现已上市,各大渠道均已现货。

卷Ⅱ针对Java 17的新特性和改进进行了修订。与以往一样,所有的章节都做了全面更新,移除了过时的内容,并且详细讨论了各种新API。

卷Ⅰ、卷Ⅱ有何不同?

如何阅读《Java核心技术》

学完本书,你将成为一个真正的 Java 程序员。本书不仅让你深入了解设计和实现 Java 应用涉及的所有基础知识和 Java 特性,还会帮助你掌握开发 Java 程序所需的全部基本技能。相信在学习Java的道路上有了本书的辅助,你的学习一定可以做到事半功倍。

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

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

相关文章

visual studio code安装c语言编译环境

目录 &#xff08;一&#xff09;Windows下安装GCC&#xff0c;下载并安装MinGW 安装MinGW 配置GCC环境变量 电脑使用CMD命令行输入 gcc -v ,查看gcc当前版本号以此判断gcc是否安装成功​编辑 &#xff08;一&#xff09;Windows下安装GCC&#xff0c;下载并安装MinGW 下载…

索引合并,能不用就不要用吧!

文章目录 1. 问题重现2. 索引合并2.1 Using intersect(...)2.2 Using union(...)2.3 Using sort_union(...)2.4 索引合并原理 3. 索引合并的问题 在前面的文章中&#xff0c;松哥和小伙伴们分享了 MySQL 中&#xff0c;InnoDB 存储引擎的数据结构&#xff0c;小伙伴们知道&…

HTB-OpenKeyS

HTB-OpenKeyS 信息收集80端口立足于JenniferJennifer -> root 信息收集 80端口 对其进行简单的SQL注入测试和NoSQL注入测试后进行目录扫描。 auth.swp文件内容如下&#xff1a; 代码不是很完整&#xff0c;只能大致了解意思&#xff08;请原谅我脑子抽了没注意是个swp交换…

USB 连接检测

文章目录 连接检测连接状态的检测带 Vbus 检测功能的 USB 设备不带 Vbus 检测功能的 USB 设备 连接前的初始化设备端主机端 建立连接过程手册规定检测时间及电平标准 连接检测 USB 协议支持热插拔的特性决定了 USB 主机必须能够动态地检测 USB 设备的连接和断开&#xff0c;这…

linux【网络编程】之网络基础

linux【网络编程】之网络基础 一、网络协议与协议分层1.1 为什么要分层1.2 OSI七层模型1.3 TCP/IP五层(或四层)模型 二、网络传输流程2.1 了解局域网2.2 同一网段内的两台主机进行文件传输2.3 跨网段的主机的文件传输 三、数据包封装和分用四、网络中的地址管理4.1 IP地址4.2 M…

【Simulink】0基础入门教程 P1 搭建自己的第一个模型 实现加减乘除四则运算

目录 工作路径的设置&#xff1a; Simulink的两种打开方式 模块的基本操作 建立一个新的空白模型&#xff0c;创建模型 加减乘除模块的名称 模块之间连线的两种方法 显示模块 Display 搭建子系统subsystem 将加法模块Add更改为多输入模块 本文记录Simulink学习&#x…

[零刻]EQ12EQ12Pro调整风扇转速教程

调整 CPU 风扇转速可以有不同的用途&#xff0c;具体取决于您的计算机和使用情况。 降低噪音&#xff1a;如果您的风扇的噪音很大&#xff0c;可以通过降低 CPU 风扇的转速来减少噪音。这可以通过在 BIOS 或中设置 CPU 风扇转速控制来实现。 提高性能&#xff1a;如果您的计算…

OpenVINO 2022.3实战一:Window 10 环境下用 OpenVINO 2022.3部署yolov5 7.0

Window 10 环境下用 OpenVINO 2022.3部署yolov5_7.0 1 下载并解压 OpenVINO Runtime OpenVINO™ Runtime 2022.3 以压缩包 (OpenVINO Archives) 的形式提供。 下载地址&#xff1a; storage.openvinotoolkit.org 下载后解压到 C:\Intel\openvino_2022.3.0 配置环境&#xff…

5月5日 8H25min|5月6日 3H10min|时间轴复盘

7:30-8:00 起床洗漱吃饭 8:00-8:30 背书 【30min】 8:30-9:40 对话单词 【1h10min】 9:45-11:30 听力精听 【2h-15min】 11:30-12:10 吃午饭吃水果 12:10-12:50 继续吃饭之前没完成的 【40min】 13:00-14:30 健身 14:35-14:43 语法 【1…

asdfghasdfghjkl

PDL1检测&#xff1a; 肿瘤细胞高表达PD-L1分子&#xff0c;与肿瘤部位浸润T淋巴细胞表面的PD-1分子结合后&#xff0c;抑制T细胞活性&#xff0c;实现肿瘤的免疫逃避。而目前PD-1/PD-L1抑制剂均是检测PD-L1的表达。 目前在NSCLC治疗中&#xff0c;对于每个PD-1/PD-L1抑制剂&a…

【Hive大数据】Hive分区表与分桶表使用详解

目录 一、分区概念产生背景 二、分区表特点 三、分区表类型 3.1 单分区 3.2 多分区 四、动态分区与静态分区 4.1 静态分区【静态加载】 4.1.1 操作演示 4.2 多重分区 4.2.1 操作演示 4.3 分区数据动态加载 4.3.1 分区表数据加载 -- 动态分区 4.3.2 操作演示 五、…

mysql事务及搜索引擎

mysql事务后半部分 加快查询速度索引会自动排序&#xff0c;&#xff08;升序&#xff09; select * from t1&#xff1b;全盘扫描 where可以索引查找show create table 索引是一个排序的列表&#xff0c;包含字段值和相应行数据的物理地址 事务是一种机制&#xff0c;一个…

Misc小总结

Misc分类 个人认为Misc中的题目可分为七大类&#xff0c;图片隐写&#xff0c;音视频隐写&#xff0c;其它隐写(PPT、word文档等隐写)&#xff0c;压缩包破解&#xff0c;流量分析&#xff0c;取证&#xff0c;编码或密码。这里面涉及的知识点当然是很多的&#xff0c;有很多你…

大学毕业设计使用python制作

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

Python标准数据类型-字符串常用方法(上)【文末送书】

✅作者简介&#xff1a;CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1 &#x1f4c3;个人主页&#xff1a;hacker707的csdn博客 &#x1f525;系列专栏&#xff1a;零基础入门篇 &#x1f4ac;个人格言&#xff1a;不断的翻越一座又一座的高山…

经验总结:(Redis NoSQL数据库快速入门)

一、Nosql概述 为什么使用Nosql 1、单机Mysql时代 90年代,一个网站的访问量一般不会太大&#xff0c;单个数据库完全够用。随着用户增多&#xff0c;网站出现以下问题 数据量增加到一定程度&#xff0c;单机数据库就放不下了数据的索引&#xff08;B Tree&#xff09;,一个机…

【Linux】进程的终止,等待(不包含进程的程序替换)

信号的部分会在后面仔细讲&#xff0c;本文不涉及 目录 1.进程终止以及退出码的理解 2.进程退出 3.进程等待 1.进程终止以及退出码的理解 1.情况分类 &#xff08;1&#xff09;正常执行完 a.结果正确 b.结果不正确 反思为什么&#xff1f; &#xff08;2&#xff…

CesiumForUnreal去掉左下角的Ion Logo

文章目录 1.实现目标2.实现过程3.参考资料1.实现目标 记录一下使用CesiumForUnreal插件过程中如何清除左下角的Cesium Ion Logo,清除前后的对比截图如下所示。 原始样式去除后2.实现过程 记录一下实现的过程(含踩坑记录,可能有一点啰嗦)。 (1)首先看一下是哪个蓝图添加的…

【STM32CubeMX】F103窗口看门狗

前言 本文记录了我学习STM32CubeMX的过程&#xff0c;方便以后回忆。我们使用的开发板是基于STM32F103C6T6的。本章记录了窗口看门狗的使用配置。要学习的话&#xff0c;注意流程一说&#xff0c;省略的内容。 基础 窗口看门狗(WWDG)属于APB1上外设。窗口看门狗(WWDG)的时钟源…

【小结】git合并分支总结

首先理清以下几个关系&#xff1a; 1、git有本地库和远程库。 ①本地仓库&#xff1a;也就是电脑上存储的代码&#xff0c;本地代码&#xff0c;一般在某个盘中。 ②远程仓库&#xff1a;是云上的库&#xff0c;比如gitee,github等等。 2、分支&#xff1a;分为本地分支和远…