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

2023-05-16

博主名字:阿玥的小东东

大家一起共进步!

目录

基础概念

优先级和结合性

不会改变用法

在全局范围内重载运算符

小结

本期送书:盼了一年的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的道路上有了本书的辅助,你的学习一定可以做到事半功倍。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 深入理解设计模式之建造者模式

    老大突然拉住我 xff0c 喜滋滋地告诉我 公司很满意我们做的模型 xff0c 又签订了一个合同 xff0c 把奔驰 宝马的车辆模型都交给我们公司制作了 xff0c 不过这次额外增加了一个新需求 汽车的启动 停止 喇叭声音 引擎声音都由客户
  • 如何改变Android-studio中的APP的名字和图标

    1 更改APP的名字 1 xff09 xff1a 我们打开app gt manifests gt AndroidManifest xml 更改Android xff1a lable 61 34 34 引号之中的文字即可 在这里我们改为QQ
  • 关于Linux下的常用软件工具

    目录 前言 xff1a vim gcc gcc c 43 43 make makefile gdb 写在最后 前言 xff1a 本篇主要介绍的是Linux下几种常用的软件的使用 关于Linux下软件的安装 xff0c yum源的配置请点击
  • 如何在局域网内搭建FTP服务器,实现信息共享

    如何在局域网内搭建FTP服务器 实现信息共享 首先打开控制面板 xff0c 点击程序 点击程序 xff0c 点击启用或关闭windows功能 xff0c 找到lnternet lnformation Services 点击前面小 xff0b
  • 笔记本电脑中Git的复制粘贴

    1 鼠标选中要选择的文本 xff01 别松开 xff01 2 按住 ctrl 43 fn别松开 xff01 3 再松开鼠标 xff0c 按住insert键 xff0c 在撤销键的上面 xff0c 复制完成 xff1b 粘贴 xff1a sh
  • Servlet正常导入依赖之后httpServlet仍然爆红

    一开始的配置文件 lt xml version 61 34 1 0 34 encoding 61 34 UTF 8 34 gt lt project xmlns 61 34 http maven apache org POM 4 0 0 3
  • Java实现生产者和消费者模式

    一 关于Object类中的wait和notify方法 生产者和消费者模式 第一 wait和notify方法任何一个java对象都有不是线程对象的方法 是java中的方法 xff0c 因为这两个方式不是object类中自带的 wait方法和n
  • spring Bean 管理

    目录 1 Bean 管理指的是两个操作 2 Bean的实例化 1 构造器实例化 2 静态工厂方式实例化 3 实例工厂方式实例化 3 Bean 管理主要三种方式 xff08 1 xff09 基于 xml 配置文件方式实现 1 基于xml方式创
  • JAVA设计模式-建造者模式

    JAVA设计模式 建造者模式 介绍 建造者模式是通过一步一步的步骤构建一个包含多个部件的对象 xff0c 每个不同的对象都是具有相同的构建过程 适用于复杂对象的构建 xff0c 用户不需要知道具体的构建细节 xff0c 只需要指定对象的类型
  • MVC框架实现用户登录注册功能(连接数据库)

    目录 一 简单理解MVC框架 二 项目结构 三 项目源码 3 1 User 3 2 UserDao 3 3 RegisterDao 3 4 servletControll 3 5 servletControllRegister 3 6 we
  • Python 第一周常见运算符作业

    一 作业详情 1 第一题 代码如下 xff1a ce 61 int input 34 Enter a defree in Celsius 34 fa 61 9 5 ce 43 32 print 34 s Celsius is s Fahre
  • 第二周python选择分支作业

    一 作业详情 1 第十九题 代码如下 xff1a s1 61 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 s2 61 2 3 6 7 10 11 14 15 18 19 22 23 26 27 30
  • 第三周python作业

    1 第四十一题 代码如下 xff1a a 61 120 for i in range 2 a while a i 61 61 0 print i end 61 34 34 a 61 a i 2 第四十二题 代码如下 xff1a hang 6
  • 字符串练习16个习题

    1 第一题 代码如下 xff1a ss 61 34 S S S 34 print ss print ss replace 34 34 34 34 2 第二题 代码如下 xff1a def f1 x sum 61 0 for it in x
  • 为什么握手是三次,挥手是四次

    三次握手 是指建立一个TCP连接时 xff0c 需要客户端和服务器总共发送3个包 三次握手的目的是连接服务器指定端口 xff0c 建立TCP连接 并同步连接双方的序列号和确认号并交换 TCP 窗口大小信息 在socket编程中 xff0c
  • hcia第二天

    1十进制与二进制转换 xff1a 除了短除法外 xff0c 还可以有如下方法 xff0c 00010101转换为十进制 1 1 43 0 2 43 1 4 43 0 8 43 1 16 61 21 ip地址相关名词解释 xff1a 网络掩码
  • Java 练习题:求平方根

    文章目录 简介程序要求思路解析代码实施 简介 平方根 xff0c 又叫二次方根 xff0c 表示为 xffe3 xff0c 其中属于非负数的平方根称之为算术平方根 xff08 arithmetic square root xff09 一个正
  • ubuntu中安装libpcap

    第一步 xff1a 下载libpcap的网址 xff08 在Ubuntu中的火狐中就可以下载 xff0c 下载的是一个安装包 xff0c 我下载的版本是libpcap 1 10 3 xff09 xff1a http www tcpdump
  • Java的顺序表的创建及对顺序表进行相关的操作

    1 顺序表的定义 xff1a 顺序表是在计算机内存中以数组的形式保存的线性表 xff0c 线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素 使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中 xff0c
  • eclipse如何重命名包名

    点击包名 xff0c F2就可以了

随机推荐

  • Java中String类的常用方法

    一 认识String类 String类在java lang包中 xff0c java使用String类创建一个字符串变量 xff0c 字符串变量属于对象 java把String类声明的final类 xff0c 不能有类 String类对象创
  • Java中Iterable、Collection、List 的常见方法签名以及含义

    三者的关系 一 Iterable Iterable接口是java 集合框架的顶级接口 实现此接口使集合对象可以通过迭代器遍历自身元素 它的成员方法如下 xff1a 方法描述iterator xff08 xff09 返回一个内部元素为T类型的
  • 常见的几种排序算法

    目录 一 冒泡排序 二 选择排序 三 插入排序 四 归并排序 五 快速排序 一 冒泡排序 冒泡排序 xff08 Bubble Sort xff09 也是一种简单直观的排序算法 它重复地走访过要排序的数列 xff0c 一次比较两个元素 xff
  • 数据结构—— 树与二叉树

    一 树的定义与基本术语 1 树的基本概念 树是n xff08 n大于等于0 xff09 个结点的有限集合 n 61 0时 xff0c 称为空树 2 树的相关术语 xff08 1 xff09 结点 xff1a 包含一个数据元素及若干指向其他结
  • MySQL表的增删查改

    目录 一 新增 二 查询 三 修改 四 删除 一 新增 xff08 Create xff09 语法 xff1a INSERT INTO table name column column VALUES value list value lis
  • 计算机组成原理相关概述

    1 计算机发展史 人类对计算的需求是从古至今一直存在的一条主脉络 根据人均算力在不断地攀升 xff0c 分为5个阶段 第一阶段 xff1a 一个国家组织共同使用一台计算机 第二阶段 xff1a 一个商业组织共同使用一台或多台计算机 第三阶段
  • 浅浅了解Servlet

    目录 一 C S架构和B S架构的区别 二 服务器 三 Servlet 四 HTTP协议 五 Servlet xff08 详解 xff09 六 Servlet应用 七 转发与重定向 八 Servlet生命周期 九 Servlet特性 十 状
  • Spring配置数据源 + 注解开发 + 整合Junit

    一 Spring配置数据源 1 1 数据源 xff08 连接池 xff09 的作用 数据源 xff08 连接池 xff09 是提高程序性能出现的 事先实例化数据源 xff0c 初始化部分连接资源 使用连接资源时从数据源中获取 使用完毕后将连
  • IDEA pom.xml添加依赖

    1 打开pom xml文件 xff0c 按住Alt 43 insert 2 搜索选取需要的添加即可 3 但看到导入的依赖报红问题 解决操作如下图 这边刷新操作完之后 xff0c 稍等一下就好了
  • 完全删除catia

    2022 9 25今天这事多少有点让人暴躁 xff0c 比如说有些东西它就是怎么删都删不掉 本帖子重点是如何卸载大多数帖子中没有说明白的CATSysDemon 一 先找到并删除catia的文件夹 卸载一个文件 xff0c 我习惯鼠标先左键选
  • 用Fragment模仿QQ界面

    概要 在android开发中 xff0c Fragment是很重要的一部分 xff0c 他有activity的特性也有他自己独特的生命周期 xff0c 使activity代码更简洁 效果演示 Demo思考问题 1 如何实现的底部三个按钮效果
  • Spring-全面详解(基础知识)

    简介 Spring5框架 内容介绍 xff1a 1 Spring概念 2 IOC容器 3 Aop 4 JDBCTEmplate 5 事物管理 6 Spring5新特性 所需的jar包 参考俺滴下面博客 Spring所需jar包 爱你的阿白
  • 监控系统zabbix—配置告警

    1 给监控项设置触发器 默认情况下 xff0c 监控项不会自动发送告警消息 需要配置触发器与告警 xff0c 并且通过通知方式发送信息给联系人 触发器 xff1a 设置条件 xff0c 当条件达到时 xff0c 将会执行某个动作 动作 xf
  • 串口打印中文乱码及注释乱码问题

    1 使用keil5代码注释出现中文乱码问题 在使用keil5中出现如下问题 xff1a 这时候的解决方法是在keil5顶头工具栏上进入 xff1a Edit Configuration xff0c 如下然后进行选择GB2312编码方式 xf
  • 蓝桥杯备赛练习(一)寻找单词中出现最多的字母

    输入一行包含一个单词 xff0c 单词只由小写英文字母组成 小蓝正在学习一门神奇的语言 xff0c 这门语言中的单词都是由小写英文字母组 成 xff0c 有些单词很长 xff0c 远远超过正常英文单词的长度 小蓝学了很长时间也记不住一些单词
  • Button点击事件

    Button点击事件一般有四种方法 xff1a 1 xff1a 匿名内部类 2 xff1a 自定义内部类 3 xff1a 通过当前Activity实现点击事件接口 4 xff1a 在xml文件中绑定 匿名内部类格式 xff1a lt But
  • 如何在Github上建立自己的个人博客网站详细教程

    概述 之前闲着没事 就利用Github建了一个个人博客网站 效果还不错 今天就来分享一下 建立自己个人博客网站的好处 1 面试装逼 这个不必多说 2 把平时积累的知识和项目记录下来 方便日后查看使用 3 不受其他博客平台的限制 准备工作 开
  • 局部变量,全局变量以及他们的生命周期和作用域

    include lt stdio h gt int mian return 0 在c语言中 xff0c 这是一段最简单的框架 当我们来讲全局变量 xff0c 局部变量时 xff0c 就从这里简单的说起 局部优先原则 首先 xff0c 我们先
  • 在Ubuntu中安装pycharm社区版

    1 在pycharm官网下载安装包 Download PyCharm Python IDE for Professional Developers by JetBrains https www jetbrains com pycharm d
  • C嘎嘎的运算符重载基础教程以及遵守规则【文末赠书三本】

    博主名字 xff1a 阿玥的小东东 大家一起共进步 xff01 目录 基础概念 优先级和结合性 不会改变用法 在全局范围内重载运算符 小结 本期送书 xff1a 盼了一年的Core Java最新版卷 xff0c 终于上市了 基础概念 运算符