类和对象--中--运算符重载、日期类实现(重要)

1.运算符重载

2.1作用:

为了让C++的新类型:类。也可以进行内置类型的运算符操作。所以就有了运算符重载。

2.2定义:

运算符重载是具有特殊名字的函数,他的名字是由operator和后⾯要定义的运算符共同构成。和其 他函数⼀样,它也具有其返回类型和参数列表以及函数体。

 这种函数一般直接在成员函数里面。和函数的格式一样,只不过函数名有要求:operator 运算符.

2.3特性:

        1.重载运算符函数的参数个数和该运算符作⽤的运算对象数量⼀样多。⼀元运算符有⼀个参数,二元运算符有两个参数,二元运算符的左侧运算对象传给第⼀个参数,右侧运算对象传给第二个参数。

        2.如果⼀个重载运算符函数是成员函数,则它的第⼀个运算对象默认传给隐式的this指针,因此运算 符重载作为成员函数时,参数⽐运算对象少⼀个。

        3.运算符重载以后,其优先级和结合性与对应的内置类型运算符保持⼀致。

        4.不能通过连接语法中没有的符号来创建新的操作符:⽐如operator@。

        5.“.* ”(通过将成员函数设置为函数指针,在类外也可以访问成员函数)、

           “::”(域作用限定符)、“sizeof”、“?:”(三目操作符)、“.”(访问对象的成员)。

                注意以上5个运算符不能重载

        6.重载操作符⾄少有⼀个 类 类型参数,不能通过运算符重载改变内置类型对象的含义。

                如: operator+(int x, int y)。不行

        7.⼀个类需要重载哪些运算符,是看哪些运算符重载后有意义。如:日期+日期,没有意义;日期-日期,有意义。

        8.重载++运算符时,有前置++和后置++,运算符重载函数名都是operator++,⽆法很好的区分。 C++规定,后置++重载时,增加⼀个int形参,跟前置++构成函数重载,⽅便区分。

        9.重载<<和>>时,需要重载为全局函数,因为重载为成员函数,this指针默认抢占了第⼀个形参位置,第⼀个形参位置是左侧运算对象,调⽤时就变成了对象<<cout,不符合使⽤习惯和可读性。 重载为全局函数把ostream/istream放到第⼀个形参位置就可以了,第⼆个形参位置当类类型对象。

2.4格式

从汇编可以看到,这二者没有任何区别。而隐式调用的逻辑,编译器帮我们加上operator了(前提是有对应运算符重载的声明和定义)。

2.5案例:

案例解析:

只是写法有所区别,别的都是对  ‘类和对象--中 ’ 知识的运用。 

Date.h

#pragma once#include <iostream>
#include <assert.h>
using namespace std;class Date {
public:void Print();Date(int year = 2024, int month = 11, int day = 22);Date(const Date& d);bool operator==(const Date& d);private:int _year = 0;int _month = 0;int _day = 0;
};

Date.cpp

#include "Date.h"void Date::Print() {cout << _year << '/' << _month << '/' << _day << endl;
}
Date::Date(int year, int month, int day) {//cout << "Date()" << endl;this->_year = year;_month = month;_day = day;
}
Date::Date(const Date& d) {this->_year = d._year;this->_month = d._month;this->_day = d._day;
}
bool Date::operator==(const Date& d) {if (_year == d._year) {if (_month == d._month) {return _day == d._day;}}return false;
}

2.日期类

通过运算符重载,让自定义类型也能 比大小、+-*/、后置/前置++。

部分解析:

  • Date+int

  • Date-int

  • 日期-日期

为了避免这样的问题,返回值需要修改。

                                                                Date.h

#pragma once#include <iostream>
#include <assert.h>
using namespace std;class Date {// 友元函数声明friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);
public:void Print();Date(int year = 2024, int month = 11, int day = 22);Date(const Date& d);
//----------------------------------------------------
//				比大小bool operator==(const Date& d);bool operator>(const Date& d);bool operator<(const Date& d);bool operator>=(const Date& d);bool operator<=(const Date& d);bool operator!=(const Date& d);
//----------------------------------------------------
// 				  + -//获取当月的天数int GetMonthDay(int _year,int _month);//日期+dayDate operator+(int day);Date& operator+=(int day);//日期-dayDate operator-(int day);Date& operator-=(int day);//日期-日期int operator-(const Date& d);
//----------------------------------------------------
//				前置++和后置++//前置++Date& operator++();//后置++Date operator++(int);Date& operator--();Date operator--(int);private:int _year = 0;int _month = 0;int _day = 0;
};// 重载 << 和 >>
//这里要访问成员变量。用的是友元
ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);

                                                                Date.cpp

#include "Date.h"void Date::Print() {cout << _year << '/' << _month << '/' << _day << endl;
}
Date::Date(int year, int month, int day) {//cout << "Date()" << endl;this->_year = year;_month = month;_day = day;
}
Date::Date(const Date& d) {this->_year = d._year;this->_month = d._month;this->_day = d._day;
}
//----------------------------------------------------
//						比大小
bool Date::operator==(const Date& d) {if (_year == d._year) {if (_month == d._month) {return _day == d._day;}}return false;
}
bool Date::operator>(const Date& d) {if (this->_year > d._year) {return true;}else if (this->_year == d._year) {if (this->_month > d._month) {return true;}else if(this->_month==d._month){return _day > d._day;}}return false;
}
bool Date::operator<(const Date& d) {return !(*this >= d);
}
bool Date::operator>=(const Date& d) {return (*this > d) || (*this == d);
}
bool Date::operator<=(const Date& d) {return (*this < d) || (*this == d);//return !(*this > d);
}
bool Date::operator!=(const Date& d) {return !(*this == d);
}
//--------------------------------------------------------------
//						+ -
int Date::GetMonthDay(int _year, int _month) {assert(_month > 0 && _month < 13);assert(_year > 0);static int a[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//判断二月if (_month == 2) {if ((_year % 4 == 0 && _year % 100 != 0) || (_year % 400 == 0)) {//是闰年,2月是29天a[2] = 29;}}return a[_month];
}
Date& Date::operator+=(int day) {_day += day;//不管走不走while,都需要获取当前月的天数while (_day > GetMonthDay(_year, _month)) {_day -= GetMonthDay(_year, _month);++_month;if (_month == 13) {_month = 1;++_year;}}return *this;
}
Date Date::operator+(int day) {Date tmp = *this;tmp += day;return tmp;
}Date& Date::operator-=(int day) {_day -= day;//只有_day是<0,才需要获取上一个月的天数while (_day <= 0) {int last_month_day = GetMonthDay(_year, _month - 1);_day += last_month_day;--_month;if (_month == 0) {_month = 12;--_year;}}return *this;
}
Date Date::operator-(int day) {Date tmp = *this;tmp -= day;return tmp;
}
int Date::operator-(const Date& d) {//先找见日期小的那一个,然后一直++。Date min = *this;Date max = d;int flag = 1;if (min > max) {min = d;max = *this;flag = -1;}//让小日期++int gap = 0;while (min != max) {++gap;++min;}return gap *flag;
}
//----------------------------------------------------------
//					前置++/后置++
Date& Date::operator++() {return (*this += 1);
}
//后置++
Date Date::operator++(int) {Date tmp = *this;*this + 1;return tmp;
}
Date& Date::operator--() {return *this -= 1;
}
Date Date::operator--(int) {Date tmp = *this;tmp - 1;return tmp;
}//-----------------------------------------------------
//				重载 << 和 >>
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;
}

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

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

相关文章

Linux基本指令【Linux系统】

文章目录 lspwdcdtouchmkdirrmdirrmmancpmvcatlessheadtailfindwhichwhereisaliasgrepzip和unzipunameexitshutdown ls 显示指定[指定方式 &#xff1a;ls空格路径]路径中非隐藏的文件 使用语法&#xff1a; ls [选项] [⽬录或⽂件] ls的常用选项 -a列出目录下的所有文件,包…

[开源]3K+ star!微软Office的平替工具,跨平台,超赞!

大家好&#xff0c;我是JavaCodexPro&#xff01; 数字化的当下&#xff0c;高效的办公工具是提升工作效率的关键&#xff0c;然而大家想到的一定是 Microsoft Office 办公软件&#xff0c;然而价格也是相当具有贵的性价比。 今天JavaCodexPro给大家分享一款超棒的开源办公套…

Django实现智能问答助手-数据库方式读取问题和答案

扩展 增加问答数据库&#xff0c;通过 Django Admin 添加问题和答案。实现更复杂的问答逻辑&#xff0c;比如使用自然语言处理&#xff08;NLP&#xff09;库。使用前端框架&#xff08;如 Bootstrap&#xff09;增强用户界面 1.注册模型到 Django Admin&#xff08;admin.py…

Spring-02-springmvc

2. 什么是SpringMVC 2.1. 概述 Spring MVC是Spring Framework的一部分&#xff0c;是基于Java实现MVC的轻量级Web框架。 为什么要学习SpringMVC呢? Spring MVC的特点&#xff1a; 轻量级&#xff0c;简单易学高效 , 基于请求响应的MVC框架与Spring兼容性好&#xff0c;无缝…

【数据结构】【线性表】一文讲完队列(附C语言源码)

队列 队列的基本概念基本术语基本操作 队列的顺序实现顺序队列结构体的创建顺序队列的初始化顺序队列入队顺序队列出队顺序队列存在的问题分析循环队列代码汇总 队列的链式实现链式队列的创建链式队列初始化-不带头结点链式队列入队-不带头节点链式队列出队-不带头结点带头结点…

手机文件可以打印出来吗

在数字化时代&#xff0c;手机已成为我们日常生活和工作中不可或缺的一部分。很多时候&#xff0c;我们需要将手机上的文件打印出来&#xff0c;无论是学习资料、工作报告还是生活文档。那么&#xff0c;手机上的文件真的可以打印出来吗&#xff1f;答案是肯定的。 直接前往打…

《Spring Boot:快速构建应用的利器》

一、Spring Boot 的崛起与优势 &#xff08;四&#xff09;丰富的生态支持 Spring Boot 拥有强大的生态系统&#xff0c;这是它在 Java 开发领域中占据重要地位的关键因素之一。 Spring Cloud 是 Spring Boot 生态中的重要组成部分&#xff0c;它为构建分布式系统的微服务架构…

爬虫实战:采集知乎XXX话题数据

目录 反爬虫的本意和其带来的挑战目标实战开发准备代码开发发现问题1. 发现问题[01]2. 发现问题[02] 解决问题1. 解决问题[01]2. 解决问题[02] 最终结果 结语 反爬虫的本意和其带来的挑战 在这个数字化时代社交媒体已经成为人们表达观点的重要渠道&#xff0c;对企业来说&…

微信小程序2-地图显示和地图标记

一、index修改页面&#xff0c;让页面能够显示地图和一个添加标记的按钮。 index.wxml <scroll-view class"scrollarea" scroll-y type"list"><view class"index_container"><map id"map" style"width: 100%; h…

Qt入门1——认识Qt的几个常用头文件和常用函数

1.头文件 ① #include <QPushButton>——“按钮”头文件&#xff1b; ② #include <QLabel>——“标签”头文件&#xff1b; ③ #include <QFont>——“字体”头文件&#xff1b; ④#include <QDebug>——输出相关信息&#xff1b; 2. 常用函数/类的基…

社交电商专业赋能高校教育与产业协同发展:定制开发AI智能名片及2+1链动商城小程序的创新驱动

摘要&#xff1a;本文围绕社交电商有望成为高校常态专业这一趋势展开深入探讨&#xff0c;剖析国家政策认可下其学科发展前景&#xff0c;着重阐述在专业建设进程中面临的师资短缺及实践教学难题。通过引入定制开发AI智能名片与21链动商城小程序&#xff0c;探究如何借助这些新…

CPU命名那些事

一、Intel CPU命名 1. 命名结构 Intel CPU 的命名通常包含以下几个部分&#xff1a; 品牌 产品线 系列 代数 具体型号 后缀 例如&#xff1a;Intel Core i7-13700K 2. 各部分含义 品牌 Intel&#xff1a;表示厂商&#xff08;几乎所有命名中都有&#xff09;。不同品…

AR智能眼镜|AR眼镜定制开发|工业AR眼镜方案

AR眼镜的设计与制造成本主要受到芯片、显示屏和光学方案的影响&#xff0c;因此选择合适的芯片至关重要。一款优秀的芯片平台能够有效提升设备性能&#xff0c;并解决多种技术挑战。例如&#xff0c;采用联发科八核2.0GHz处理器&#xff0c;结合12nm制程工艺&#xff0c;这种低…

第二十一周机器学习笔记:动手深度学习之——数据操作、数据预处理

第二十周周报 摘要Abstract一、动手深度学习1. 数据操作1.1 数据基本操作1.2 数据运算1.2.1 广播机制 1.3 索引和切片 2. 数据预处理 二、复习RNN与LSTM1. Recurrent Neural Network&#xff08;RNN&#xff0c;循环神经网络&#xff09;1.1 词汇vector的编码方式1.2 RNN的变形…

ThinkPad t61p 作SMB服务器,打印服务器,pc ,android ,ipad利用此服务器互传文件

1.在t61p上安装win7 2,配置好smb 服务 3.再安装好打印驱动程序 4.pc与win7利用系统的网络互相发现,映射为硬盘使用。 5.android&#xff0c;ipad安装ES文件浏览器访问win7 共享文件夹&#xff0c;互传文件。 6.android手机安装FE文件浏览器&#xff0c;可以利用花生壳外网…

【深度学习之二】正则化函数(weight decay, dropout, label smoothing, and etc)详解,以及不同的函数适用的场景

在深度学习中正则化函数的重要性不言而喻&#xff0c;今天主要总结一些当前常用的一些正则化函数 在深度学习中&#xff0c;正则化&#xff08;Regularization&#xff09;是一种防止模型过拟合的技术。过拟合指的是模型在训练数据上表现很好&#xff0c;但在未见过的测试数据…

神经网络(系统性学习二):单层神经网络(感知机)

此前篇章&#xff1a; 神经网络中常用的激活函数 神经网络&#xff08;系统性学习一&#xff09;&#xff1a;入门篇 单层神经网络&#xff08;又叫感知机&#xff09; 单层网络是最简单的全连接神经网络&#xff0c;它仅有输入层和输出层&#xff0c;没有隐藏层。即&#x…

Linux 手动升级软件保姆级教程,适用所有软件,不限于麒麟等国产系统

1、检查软件版本&#xff0c;及是否安装 openssh为例 是否安装 rpm -qa|grep openssh 备份 mv /etc/ssh/ /home/ssh-bakmv /usr/bin/ssh /usr/bin/ssh.bakmv /usr/sbin/sshd /usr/sbin/sshd.bakmv /etc/pam.d/sshd /etc/pam.d/sshd.old2、机器如果不在身边&#xff0c;机器…

【大数据学习 | Spark-Core】Spark的改变分区的算子

当分区由多变少时&#xff0c;不需要shuffle&#xff0c;也就是父RDD与子RDD之间是窄依赖。 当分区由少变多时&#xff0c;是需要shuffle的。 但极端情况下&#xff08;1000个分区变成1个分区)&#xff0c;这时如果将shuffle设置为false&#xff0c;父子RDD是窄依赖关系&…

java操作doc——java利用Aspose.Words操作Word文档并动态设置单元格合并

在实际工作中&#xff0c;如果业务线是管理类项目或者存在大量报表需要导出的业务时&#xff0c;可以借助第三方插件实现其对应功能。 尤其是需要对word文档的动态操作或者模板数据的定向合并&#xff0c;使用Aspose会相对来说容易一些&#xff0c;而且相关文档比较完整&#…