当前位置: 首页 > news >正文

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

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.mrgr.cn/news/77983.html

相关文章:

  • SQL 分页查询详解
  • 短视频矩阵矩阵,矩阵号策略
  • C语言中的结构体,指针,联合体的使用
  • Can UDS 学习记录
  • 百大冷知识系列:天文
  • C 语言复习总结记录三
  • 09 —— Webpack搭建开发环境
  • 【前端】JavaScript 作用域全面解析
  • 编程中的快捷操作
  • 运维Tips:Docker或K8s集群拉取Harbor私有容器镜像仓库配置指南
  • .net core MVC入门(一)
  • 三汇&网易|认知实习报告
  • 【CSP CCF记录】201812-2第15次认证 小明放学
  • 华为昇腾 acl_pytorch
  • Node教程和实战
  • MCU(一) 时钟详解 —— 以 GD32E103 时钟树结构为例
  • C++设计模式-模板模式,Template Method
  • Vue 中 data 属性为函数的深度剖析:原理、区别与实践
  • aws服务--机密数据存储KMS(1)介绍和使用
  • 16:(标准库)ADC三:使用外部触发启动ADC/模拟看门狗
  • [OpenHarmony5.0][环境][教程]OpenHarmony 5.0源码在WSL2 Ubuntu22.04 编译环境搭建教程
  • C++设计模式-策略模式-StrategyMethod
  • 分割一切2.0,SAM2详解
  • 接口性能优化宝典:解决性能瓶颈的策略与实践
  • java 二分查找 方法 详解
  • 虚幻引擎---术语篇