运算符重载详解(完全版)

1.运算符重载

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

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

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

注意点

  • 不能通过连接其他符号来创建新的操作符,比如operator@
  • 重载操作符必须有一个类类型参数,比如不可以对整型进行重载
  • 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不能改变其含义
  • 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
  • .*  ::    sizeof  ?:   . 以上5个运算符不能重载 
class Date
{
public://构造函数Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//bool operator==(Date* this,const Date& d2)//这里需要注意的是,左操作数是this,指向调用函数的对象bool operator==(const Date& d2){return _year == d2._year&& _month == d2._month&& _day == d2._day;}
private:int _year;int _month;int _day;
};

2.赋值运算符重载

2.1赋值运算符重载格式

  • 参数类型:const T&,传递引用可以提高传参效率
  • 返回值类型:T&,返回引用可以提高返回的效率,有返回值的目的是为了支持连续赋值
  • 检测是否自己给自己赋值
  • 返回*this:要复合连续赋值的含义  
class Date
{
public://构造函数Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//拷贝构造Date(const Date& d){_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;}
private:int _year;int _month;int _day;
};

 2.2注意点

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

原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,所以赋值运算符重载只能是类的成员函数

2.用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。

注意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值

class Time
{
public:Time(){_hour = 1;_minute = 1;_second = 1;}Time& operator=(const Time& t){if (this != &t){_hour = t._hour;_minute = t._minute;_second = t._second;}return *this;}
private:int _hour;int _minute;int _second;
};class Date
{
private://内置类型int _year = 1970;int _month = 1;int _day = 1;//自定义类型Time _t;
};int main()
{Date d1;Date d2;d1 = d2;return 0;
}

3.前置++和后置++重载

  • 前置自增运算符重载通常不接收任何参数,其目的是直接对当前对象进行增加操作,然后返回当前对象的引用。 
  • 后置自增运算符重载接收一个 int 类型的参数(通常不使用这个参数),其目的是先保存当前对象的副本,然后对当前对象进行增加操作,最后返回之前保存的副本。
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//前置++:返回+1之后的结果,注意,this指向的对象函数结束后不会销毁,故以引用方式返回提高效率Date& operator++(){_day += 1;return *this;}//后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器自动传递//后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时先将this保存一份,然后给this+1//temp是临时对象,因此只能以值的方式返回,不能返回引用Date operator++(int){Date temp(*this);_day += 1;return temp;}
private:int _year;int _month;int _day;
};int main()
{Date d;Date d1(2024, 6, 25);d = d1++;//2024,6,25d = ++d1;//2024,6,26return 0;
}

4.函数重载与运算符重载

函数重载:让函数名相同,但是参数不同的函数存在

运算符重载:让自定义类型可以用运算符,并且控制运算符的行为,增强可读性

多个同一运算符重载可以构成函数重载

Date operator-(int day);//日期-天数
int operator-(const Date& d);//日期-日期

5.重载流插入和提取运算符

目的:为了实现自定义类型的输入和输出,注意自定义类型本质是内置类型

重载流插入运算符,我们可以尝试将其重载为Date类的成员函数

void Date::operator<<(ostream& out)
{out<<_year<<“年”<<_month<<"月”<<_day<<"日”<<endl;
}

这里其实有两个参数,隐含的Date* this占据了第一个参数的位置

我们习惯调用的方式

cout<<d1;

不能用了,因为cout的类型时ostream,d1的类型是Date,这和函数的参数列表的顺序不一致,不能用。如果我们想调用,只能写成d1<<cout;这不符合我们的习惯。所以说,operator<<想重载为成员函数,可以,但用起来不符合正常逻辑,不建议这样处理,我们一般将其重载为全局函数

//operator<<(cout,d1)
void operator<<(ostream& out,const Date& d)
{out<<d._year<<"年"<<d._month<<"月"<<d._day<<"日"<<endl;
}

再进行修改,便可以实现链式输出。链式输出的关键在于重载的操作符返回了一个 ostream 类型的引用,当你重载 << 操作符时,返回类型必须是 ostream 的引用。这意味着当你使用 << 操作符时,表达式可以继续被用在另一个 << 表达式中。

ostream& operator<<(ostream& out,const Date& d)
{out<<d._year<<"年"<<d._month<<"月"<<d._day<<"日"<<endl;return out;
}

同理,重载流提取操作符也是如此

istream& operator>>(istream& in,Date& d)
{cout<<"请依次输入年月日:>";in>>d._year>>d._month>>d._day;return in;
}

6.const成员

const成员函数是一个特殊的成员函数,它通过在函数声明的末尾加上const修饰符来定义。这样的成员函数承诺不会修改调用它的对象的状态,即它不会修改类的非静态成员变量。

格式类型  函数名(参数列表)const

特点

  • 不可修改成员变量:在const成员函数内部,对类的非静态成员变量的修改是不允许的,否则会导致编译错误。
  • 可调用性:如果一个对象被声明为const,那么只有const成员函数才能被调用。这是因为非const成员函数可能会改变对象的状态,这不符合对象的常量性。
  • 提高安全性:使用const成员函数可以增加代码的安全性,因为它提供了明确的保证,即函数不会修改对象的状态。这有助于捕获潜在的bug,并使代码更易于理解和维护

示例:

class  MyClass  {
private:int  value;public:MyClass(int  val)  :  value(val)  {}//  const成员函数int  getValue()  const  {return  value;  //  可以读取成员变量}//  非const成员函数void  setValue(int  val)  {value  =  val;  //  可以修改成员变量}
};

 在这个例子中,getValue是一个const成员函数,它只读取成员变量value而不修改它。相反,setValue是一个非const成员函数,它可以修改成员变量value。

在下一篇文章中,我们将实现日期类来巩固运算符重载的知识

点赞收藏关注是博主不断生产优质好文的动力哦~

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

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

相关文章

Interview preparation--Elasticsearch写入原理与调优

ES的写入过程 ES支持的写操作 create&#xff1a; create操作不同于put操作&#xff0c;put操作的时候如果当前put的数据存在则会被覆盖&#xff0c;如果put操作的时候加上操作类型create&#xff0c;如果数据存在则会返回失败&#xff0c;比如&#xff1a;PUT /pruduct/_cre…

Ubuntu20.04安装python2和python3及版本配置

Ubuntu20.04安装python2和python3及版本配置_ubuntu 20.04 python3-CSDN博客https://blog.csdn.net/pangc2014/article/details/117407413 >>>ubuntu 安装源码python2_mob649e8161c39d的技术博客_51CTO博客https://blog.51cto.com/u_16175489/7327966

大厂薪资福利篇第四弹:字节跳动

欢迎来到绝命Coding&#xff01; 今天继续更新大家最关心的 大厂薪资福利系列&#xff01; 往期分享&#xff1a; 福利开水喝不完&#xff1f;大厂薪资福利篇&#xff01;美团 职场文化发源地&#xff1f;大厂薪资福利篇&#xff01;阿里巴巴 给这么多&#xff01;还能带宠物上…

MFC案例:自制工具条(Toolbar)按钮的小程序

程序目标&#xff1a;在基于对话框的MFC项目中&#xff0c;自制三个 Toolbar 按钮&#xff08;用颜色区分&#xff0c;分别为红、绿、蓝&#xff09;&#xff1b;程序运行时&#xff0c;单击红色按钮显示一个红色的填充椭圆&#xff1b;再单击绿色按钮则进行清屏&#xff1b;最…

[hive] posexplode生成从去年一月一号,到本月的月时间表

生成从去年一月一号&#xff0c;到本月的月时间表 posexplode用法&#xff1a; lateral view 表别名 as 序号列名,数组中的元素的名 1、生成序列 SELECT time_stamp_fist_day_of_last_year,--去年第一天的时间戳numfrom(SELECTsplit(repeat_o,,) o_array,time_stamp_fist_da…

用英文介绍纽约:NEW YORK, USA‘s MEGACITY

NEW YORK, USA’s MEGACITY | America’s Largest City Link: https://www.youtube.com/watch?vdzjQ-akB3BI&listPLmSQiOQJmbZ7TU39cyx7gizM9i8nOuZXy&index24 The story of New York City, America’s megalopolis. Summary Paragraph 1: The Historical Developm…

Chrome插件:​Vue.js Devtools 高效地开发和调试

在现代前端开发中&#xff0c;Vue.js因其灵活性和性能优势&#xff0c;受到越来越多开发者的青睐。然而&#xff0c;随着项目规模的扩大&#xff0c;调试和优化变得愈发复杂。幸运的是&#xff0c;Vue.js Devtools的出现&#xff0c;为开发者提供了一套强大的工具集&#xff0c…

vue大屏适配方案

前言 开发过大屏的铁汁们应该知道&#xff0c;前期最头疼的就是大屏适配&#xff0c;由于大屏项目需要在市面上不是很常见的显示器上进行展示&#xff0c;所以要根据不同的尺寸进行适配&#xff0c;今天我将为大家分享的我使用的大屏适配方案&#xff0c;话不多说&#xff0c;直…

Matlab|风光及负荷多场景随机生成与缩减

目录 1 主要内容 计算模型 场景生成与聚类方法应用 2 部分程序 3 程序结果 4 下载链接 1 主要内容 该程序方法复现了《融合多场景分析的交直流混合微电网多时间尺度随机优化调度策略》3.1节基于多场景技术的随机性建模部分&#xff0c;该部分是随机优化调度的重要组成部分…

轻松掌握:工科生如何高效阅读国际期刊和撰写论文(下)

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三连支…

透明屏幕的魅力:为何它如此受欢迎

在科技日新月异的今天&#xff0c;透明屏幕技术以其独特的魅力和广泛的应用前景&#xff0c;逐渐成为了科技领域的一颗璀璨明星。从智能手机、平板电脑到大型显示屏&#xff0c;透明屏幕技术以其前所未有的视觉体验和实用性&#xff0c;赢得了广大消费者的喜爱。 一、透明屏幕的…

docker 镜像突然拉取不了,教你解决

最近我们可以发现&#xff0c;在Linux系统里拉取不了镜像了&#xff0c;翻墙也拉取不了&#xff0c;这时候我们可以有一个新的docker 镜像同步网站来解决这个问题 一、首先打开镜像官网&#xff08;需要翻墙&#xff09; https://hub.docker.com/ 然后搜索一个镜像 搜索最新…

Nginx实战:简单登录验证配置(基于openssl)

本文提供的是基于openssl创建的密码文件,对nginx指定的location访问。进行登录验证的配置方式。 1、验证页面配置 我的nginx实验环境是直接yum安装的,如果是自己编译安装的那么对应目录就是自己安装配置的目录。 先在/usr/share/nginx/html下创建一个usertest.html,里面添加…

Spring Cache常见问题解决

目录 一 报错:Null key returned for cache operation 二 报错&#xff1a;类型转换异常 三 取出的数据为null 一 报错:Null key returned for cache operation 这里报错有两种情况&#xff1a; 第一&#xff0c;如果你在新增的方法上使用Cacheable注解&#xff0c;那么肯定是…

绝望中迎来曙光,阿里大模型算法岗 Offer 突然来了!

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型技术趋势、算法项目落地经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。 总结链接如…

用定时器T1中断控制两个LED以不同周期闪烁

#include<reg51.h> // 包含51单片机寄存器定义的头文件 sbit D1P2^0; //将D1位定义为P2.0引脚 sbit D2P2^1; //将D2位定义为P2.1引脚 unsigned char Countor1; //设置全局变量&#xff0c;储存定时器T1中断次数 unsigned char Countor2; //设置全局变量&#xff0c;储…

virutalBox安装debian并配置docker环境

下载镜像 https://gemmei.ftp.acc.umu.se/debian-cd/current/amd64/iso-cd/debian-12.5.0-amd64-netinst.iso 虚拟机安装 如何在Virtual Box 上安装Debian系统_virtual box debian iso netinst-CSDN博客 启动命令行模式 如何设置Debian图形启动或命令行界面启动&#xff1…

什么是Cookie?有什么用?如何清除浏览器中的Cookie?

互联网上的每一次点击和每一个选择都可能被一种名为Cookie的技术记录下来。但Cookie是什么&#xff1f;我们在网站上登录时&#xff0c;为什么经常会被问及是否接受Cookie&#xff1f;接受Cookie登录会不会影响我们的在线隐私&#xff1f; Cookie是什么&#xff1f; Cookie是一…

S-Clustr(影子集群)V3 高并发,去中心化,多节点控制

S-Clustr 项目地址:https://github.com/MartinxMax/S-Clustr/releases/tag/S-Clustr-V3.0 Maptnh Не ограничивайте свои действия виртуальным миром. GitHub: Maptnh Jay Steinberg Man kann die Menschen, die man hasst, in d…

体育赛事翻译欧洲杯足球翻译术语分享

欧洲杯又称欧洲足球锦标赛&#xff0c;是世界上受欢迎和具影响力的国际体育赛事之一&#xff0c;有关足球翻译的术语分享如下&#xff1a; penalty mark (点球)罚球点,midfielder 前卫,center forward 中锋 full back 后卫,bicycle kick / overhead kick 倒钩球,chest-high ba…