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

目录

1.运算符重载

2.日期类


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

cpp 复制代码
#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);

	//日期+day
	Date operator+(int day);
	Date& operator+=(int day);

	//日期-day
	Date 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

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;
}
相关推荐
桃园码工9 分钟前
第三章:基本语法 1.注释 --Go 语言轻松入门
开发语言·后端·golang·轻松入门·go 语言
糯诺诺米团9 分钟前
Qt中模拟鼠标消息并与系统鼠标消息进行区分
c++·qt·计算机外设
白子寰26 分钟前
【C++打怪之路Lv16】-- map && set
开发语言·c++
沐风ya26 分钟前
python代码示例(读取excel文件,自动播放音频)
开发语言·python
王子良.27 分钟前
常见的排序算法
大数据·数据结构·经验分享·python·学习·算法·排序算法
何朴尧44 分钟前
工厂方法模式与抽象工厂模式
c++·工厂方法模式·抽象工厂模式
終不似少年遊*1 小时前
Python开发环境搭建+conda管理环境
开发语言·笔记·python·学习·conda
froginwe111 小时前
HTML DOM 修改 HTML 内容
开发语言
萨达大1 小时前
23种设计模式-工厂方法(Factory Method)设计模式
c++·设计模式·工厂方法模式·软考·创建型设计模式·软件设计师
借雨醉东风1 小时前
C++实现网格交易的例子
开发语言·c++·算法