首页 > 编程语言 >C++运算符重载

C++运算符重载

时间:2024-08-19 22:58:32浏览次数:15  
标签:int ._ C++ month 运算符 Date year 重载 day

文章目录

一、运算符重载

1、规定
  • C++允许我们对类类型使用运算符,但要我们自己通过运算符重载完成类类型的运算,如果没有对应的运算符重载就会报错。
  • 运算符重载需要使用特殊关键词operator后跟运算符来完成定义。它跟函数写法一样,具有返回值,函数参数类型,和函数体。
  • 运算符重载不会改变运算符的优先级和结合性。
  • 运算符重载不能重载C++里没有规定的符号,但 .* :: sizeof ?: . 这五个运算符不能重载。

.* 运算符的作用,用于定义类的成员函数指针

//类成员函数指针
#include <iostream>
using namespace std;

class A
{
public:
	void fun()
	{
		cout << "A::fun" << endl;
	}
};

typedef void(A::*PF)();
int main()
{
	void(A::*pf)();
	pf = &A::fun;
	PF p = &A::fun;
	//调用类函数要先创建一个对象
	A a;
	//然后调用函数指针用.*
	(a.*pf)();
	return 0;
}
2、operator关键词的使用

对于类类型的使用运算符编译器是不知道要干嘛的就需要自己写函数,自己实现功能。

就比如日期类的大小比较。

在这里插入图片描述


多少天后日期是多少

	//返回每该月有多少天
	int GetMonthDay()
	{
		static int  arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if (_month == 2 && (_year % 4 == 0 && _year % 100 != 0 || _year%400==0))
		{
			return 29;
		}
		return arr[_month];
	}

	Date operator+=(int day)
	{
		_day += day;
		while (_day > (this->GetMonthDay()))
		{
			_day -= this->GetMonthDay();
			_month++;
			if (_month >= 13)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}

判断日期是否相等

bool operator==(const Date& d)
{
	return (_year == d._year && _month == d._month && _day == d._day);
}
  • 前置operator++ 和 后置operator++

编译器会做特殊处理,后置++会多个int类型的形参

	//前置++
	//出了作用域值还在,用引用返回可以减少拷贝
	Date& operator++()
	{
		_day++;
		if (_day > this->GetMonthDay())
		{
			_day -= this->GetMonthDay();
			_month++;
			if (_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}

	//后置++
	Date operator++(int i)
	{
		Date tmp = *this;
		_day++;
		if (_day > this->GetMonthDay())
		{
			_day -= this->GetMonthDay();
			_month++;
			if (_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
		return tmp;
	}

二、赋值运算符的重载

1、功能
  • 对两个已经存在的类的对象进行赋值拷贝操作。

  • 要跟拷贝构造区分,拷贝构造是一个已经存在,给另一个初始化时进行的拷贝操作。

  • 如果不写赋值运算符重载函数,系统会自动生成,但是浅拷贝,一个字节一个字节的拷贝,对于占用资源的还是要自己写才好。

  • 支持连续赋值,所以返回值就是类类型本身。

	//赋值运算符重载
	Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;

		return *this;
	}

总结如果显示写了析构,就要显示写赋值运算符重载。

2、使用

日期类比较大小

#include <iostream>
#include <stdbool.h>

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1);

	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);

private:
	int _year;
	int _month;
	int _day;
};

Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
}

bool Date::operator <(const Date& d)
{
	if (_year < d._year)
	{
		return true;
	}
	else if (_year == d._year && _month < d._month)
	{
		return true;
	}
	else if (_year == d._year && _month < d._month && _day < d._day)
	{
		return true;
	}
	return false;
}
bool Date:: operator >(const Date& d)
{
	return !(*this < d || *this == d);
}
bool Date::operator <=(const Date& d)
{
	return (*this < d || *this == d);
}
bool Date::operator >=(const Date& d)
{
	return !(*this < d);
}
bool Date::operator ==(const Date& d)
{
	return _year == d._year && _month == d._month && _day == d._day;
}
bool Date::operator !=(const Date& d)
{
	return !(*this == d);
}

日期 - 日期,日期 + 天数,日期 - 天数,这些都是有意义的

int Date::operator-(const Date& d)
{
	int sum = 0;
	if (*this > d)
	{
		if (d._year < _year)
		{
			for (int i = d._year + 1; i < _year; i++)
			{
				if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0)
				{
					sum += 366;
				}
				else
				{
					sum += 365;
				}
			}
		
		
			for (int i = d._month + 1; i <= 12; i++)
			{
				sum += GetMonthDay(d._year, i);
			}
			sum += (GetMonthDay(d._year, d._month) - d._day);

			for (int i = 1; i < _month; i++)
			{
				sum += GetMonthDay(_year, i);
			}
		}
		else if(d._year == _year)
		{
			if(d._month == _month)
				sum -= d._day;
			else
			{
				for (int i = d._month+1; i < _month; i++)
				{
					sum += GetMonthDay(_year, i);
				}
				sum += (GetMonthDay(d._year, d._month) - d._day);
			}
			
		}
		
		
		sum += _day;
	}
	else
	{
		if (_year < d._year)
		{
			for (int i = _year + 1; i < d._year; i++)
			{
				if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0)
				{
					sum -= 366;
				}
				else
				{
					sum -= 365;
				}
			}


			for (int i = _month + 1; i <= 12; i++)
			{
				sum -= GetMonthDay(_year, i);
			}
			sum -= (GetMonthDay(_year, _month) - _day);

			for (int i = 1; i < d._month; i++)
			{
				sum -= GetMonthDay(d._year, i);
			}
		}
		else if (d._year == _year)
		{
			if (d._month == _month)
				sum += _day;
			else
			{
				for (int i = _month+1; i < d._month; i++)
				{
					sum -= GetMonthDay(_year, i);
				}
				sum -= (GetMonthDay(_year, _month) - _day);
			}

		}


		sum -= d._day;
	}
	return sum;
}


Date& Date::operator+=(const int day)
{
	if (day < 0)
	{
		return *this -= -day;
	}
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month >= 13)
		{
			_year++;
			_month = 1;
		}
	}
	return *this;
}

Date Date::operator+(const int day)
{
	Date tmp = *this;
	tmp += day;
	return tmp;
}

Date& Date::operator-=(const int day)
{
	if (day < 0)
	{
		return *this += -day;
	}
	_day -= day;
	while (_day <= 0)
	{
		_day += GetMonthDay(_year, _month);
		_month--;
		if (_month <= 0)
		{
			_year--;
			_month = 12;
		}
	}
	return *this;
}
Date Date::operator-(const int day)
{
	Date tmp = *this;
	tmp -= day;
	return tmp;
}

输入(流提取)>>,输出(流插入)<< 运算符

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

标签:int,._,C++,month,运算符,Date,year,重载,day
From: https://blog.csdn.net/2401_83305953/article/details/141263348

相关文章

  • 【C++】看完就会--右值引用!!!
    右值引用一、什么是右值?什么是左值?二、右值引用三、右值引用的好处四、万能引用五、完美转发一、什么是右值?什么是左值?首先,当我们看到右值的时候,我们很自然的就会产生疑问?什么的右边呢?等号的右边吗?那么如果是按赋值=符号的右边来定义的话,那么,左值是不是就是=符号......
  • Oracle运算符:从等号到空值运算的使用技巧
    在Oracle数据库中,关系运算符和逻辑运算符用于在SQL查询中定义条件。1.等号(=)运算符作用:用于精确匹配字段的值。适用场景:适用于比较数值、字符串、日期等数据类型,要求条件严格相等。例子:SELECTename,salFROMempWHEREdeptno=10;查询部门编号为10的所有员工姓名和......
  • 【LGR-196-Div.4】洛谷入门赛 #26 题A - H 详细题解--优化思路简洁代码(C++,Python语
    前言:    觉得这个比赛很有意思的,都是暴力题,涉及一些细节,难度比较适合刚学编程语言的,可以很好的锻炼基础还有手速,最后两题也是比较有意思,之后也准备更新atc的比赛题解和洛谷的一些高质量比赛题解(算法网瘾就是想参加各种比赛)   如果觉得有帮助,或者觉得我写的好,......
  • 生产者消费者问题-C++代码实现
    生产者消费者问题C++代码本文主要记录面试中手撕代码环节比较经常考察的生产者消费者问题,方便后续巩固和查看#include<iostream>#include<thread>#include<mutex>#include<condition_variable>#include<queue>#include<functional>usingnamespacestd;classProd......
  • 配置 昇腾 Ascend C/C++ 开发环境
    配置昇腾AscendC/C++开发环境flyfish这里以OrangePiAiPro为例先说如何配置MindStudio,然后再说如何查看OrangePiAiPro的一些信息OrangePiAIPro开发板是香橙派联合华为精心打造的高性能AI开发板,其搭载了昇腾AI处理器。Linux桌面系统的默认登录用户为H......
  • C++ 获取Linux 服务器CPU占用率+内存空闲率(亲测绝对可以运行)
    转自:C++获取Linux服务器CPU占用率+内存空闲率(亲测绝对可以运行)-远征i-博客园(cnblogs.com)代码来自网络,部分修改,亲测绝对可用C++:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<iostream>#include<unistd.h>usingnamespacestd;type......
  • 牛客网习题——通过C++实现
    一、目标实现下面4道练习题增强C++代码能力。1.求1+2+3+...+n_牛客题霸_牛客网(nowcoder.com)2.计算日期到天数转换_牛客题霸_牛客网(nowcoder.com)3.日期差值_牛客题霸_牛客网(nowcoder.com)4.打印日期_牛客题霸_牛客网(nowcoder.com)二、对目标的实现 1.求1+2+3+......
  • C++图笔记(三)有向无环图(及最小生成树(略))以及剩下的排序
    目录一,定义:1,有向无环图 2,拓朴排序 1,每个顶点出现且仅仅出现一次。 2,若存在一条从顶点A到顶点B的路径,那么在序列中顶点A出现在顶点B的前面。二,DAG的性质性质1.  从任意一个起点进行dfs,必不会陷入死循环。性质2.  入度为0的点信息确定,删掉入度为0的点......
  • C++--二叉搜索树
     目录 1.1二叉搜索树概念1.2二叉搜索树操作 1.2.1查找1.2.2插入1.2.3删除2.3二叉搜索树实现 2.4二叉搜索树的应用 2.5二叉搜索树的性能分析 1.1二叉搜索树概念二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:--若它的左子......
  • C/C++语言基础--指针三大专题详解2(指针与数组关系,动态内存分配,代码均可)
    本专栏目的更新C/C++的基础语法,包括C++的一些新特性前言指针是C/C++的灵魂,和内存地址相关联,运行的时候速度快,但是同时也有很多细节和规范要注意的,毕竟内存泄漏是很恐怖的指针打算分三篇文章进行讲解,本专题是二,介绍了指针和数组的关系、动态内存如何分配和释放等问题专题......