C++类和对象(5)——运算符重载(以日期类为例)

2024-08-31 03:44

本文主要是介绍C++类和对象(5)——运算符重载(以日期类为例),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

运算符重载的作用

假设我们此时实现了日期类的运算符重载,我们就可以

实现如图的很多功能,完成日期计算器的底层代码。

运算符重载关键字

运算符重载的关键字是operator。

比如你想重载‘+’运算符,那么语法格式就是

返回类型 + operator + ‘+’ +(形参),

以日期类为例,

Date operator+(int day)const;

有const关键字是因为这个重载不修改对象本身(*this)的值,如下图的d1不被改变。

Date d3 = d1 + 100;

以下运算符不能重载:

1.     ?:

2.     sizeof

3.     

4.      :: 

5.      .*

日期类的运算符重载

以下是日期类的声明,待会逐一实现运算符重载。

#pragma once
#include<iostream>
using namespace std;
class Date
{friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& out, Date& d);public:Date(int year = 1990, int month = 1, int day = 1);~Date();int GetMonthDay(int year, int month){static int a[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };if ((month == 2) && ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0))){return 29;}return a[month];}Date(const Date& d);void print()const;Date& operator=(const Date& d);Date& operator+=(int day);Date operator+(int day)const;Date& operator-=(int day);Date operator-(int day)const;Date& operator++();Date operator++(int);Date& operator--();Date operator--(int);bool operator>(const Date& d)const;bool operator==(const Date& d)const;bool operator >= (const Date& d)const;bool operator < (const Date& d)const;bool operator <= (const Date& d)const;bool operator != (const Date& d)const;int operator-(const Date& d)const;private:int _year;int _month;int _day;
};ostream& operator<<(ostream& out, const Date& d);istream& operator>>(istream& out, Date& d);

构造、拷贝构造、析构函数的实现(非重载内容可跳过)

我以前写过两篇博客介绍构造、拷贝构造、析构函数,感兴趣的朋友可以看看。

http://t.csdnimg.cn/DedK1

http://t.csdnimg.cn/LWuj2

Date::Date(int year, int month, int day) :_year(year),_month(month),_day(day)
{}Date::~Date() {}Date::Date(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;
}

重载 =

Date& Date::operator=(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;return *this;
}

我们运用的场景如下:

Date d1(2000, 1, 1);
Date d2(2001, 2, 2);
d1 = d2;

当我们重载=时,将d2赋值给d1,改变了d1的值,所以重载=的返回类型为 Date& ,返回*this

重载+=

要实现日期+天数的功能,我们要先编写一个函数GetMonthDay,这个函数可以直接写在类的声明里。

int GetMonthDay(int year, int month)
{static int a[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };if ((month == 2) && ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0))){return 29;}return a[month];
}

接着实现+=的重载

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

通过while循环实现天数的正确叠加、月份和年份的增加。

注意返回类型是Date&,因为

Date d1(2000, 1, 1);
d1 += d1 + 100;

d1重载+=时,d1的值会被改变 !

重载+

这一步我们可以通过写过的的+=重载偷懒😎

Date Date::operator+(int day)const
{Date temp = *this;
//+=已经重载过了,可以直接用temp += day;return temp;
}

注意返回类型是Date,因为

Date d3 = d1 + 100;

调用的时候是d1重载+,d1的值没有被改变。

重载-=(计算这个日期前x天是几号)

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

重载-

Date Date::operator-(int day)const
{Date temp = *this;temp -= day;return temp;
}

重载前置++

Date& Date::operator++()
{*this += 1;return *this;
}

这里也用+=重载偷懒了😉

重载后置++

Date Date::operator++(int)
{Date temp = *this;++*this;return temp;
}

注意,为了区分后置++与前置++,后置++的传参有一个int形参!

并且,后置++的返回值为Date, 前置++的返回值为Date&;

因为:

如上图所示,

d2的值与d1的原始值相等 ,

当d1++用过一次之后,d1的值才会+1.

这也就解释了为什么后置++的返回值为Date, 前置++的返回值为Date&;

后置++需要temp变量存放*this的值。

重载前置--

Date& Date::operator--()
{*this -= 1;return *this;
}

用-=偷懒。。

重载后置--

Date Date::operator--(int)
{Date temp = *this;--*this;return temp;
}

重载>

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

重载==

bool Date::operator==(const Date& d)const
{return (_year == d._year) && (_month == d._month) && (_day == d._day);
}

重载>=

bool Date::operator >= (const Date& d)const
{return (*this > d) || (*this == d);
}

重载<

bool Date::operator < (const Date& d)const
{return !(*this >= d);
}

重载<=

bool Date::operator <= (const Date& d)const
{return !(*this > d);
}

重载!=

bool Date::operator != (const Date& d)const
{return !(*this == d);
}

重载<<

ostream& operator<<(ostream& out, const Date& d)
{out << d._year << '-' << d._month << '-' << d._day << endl;return out;
}

这不是Date类的成员函数,而是全局函数。

为了能访问私有成员_year,_month,_day,

我们要把这个函数变成友元函数,如下:

重载>>

//这里的形参Date& d的前面不能添加const关键字,因为d的值待会要改变
istream& operator>>(istream& in, Date& d)
{cout << "" << endl;in >> d._year >> d._month >> d._day;return in;
}

重载-(计算两个时间之间差几天)

int Date::operator-(const Date& d)const
{Date max = *this;Date min = d;if (*this < d){max = d;min = *this;}int ret = 0;while (min != max){++min;++ret;}return ret;
}

我的另一篇博客讲了详细的实现思路http://t.csdnimg.cn/gk7cK

这篇关于C++类和对象(5)——运算符重载(以日期类为例)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1122795

相关文章

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

使用MapStruct实现Java对象映射的示例代码

《使用MapStruct实现Java对象映射的示例代码》本文主要介绍了使用MapStruct实现Java对象映射的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、什么是 MapStruct?二、实战演练:三步集成 MapStruct第一步:添加 Mave

C++中处理文本数据char与string的终极对比指南

《C++中处理文本数据char与string的终极对比指南》在C++编程中char和string是两种用于处理字符数据的类型,但它们在使用方式和功能上有显著的不同,:本文主要介绍C++中处理文本数... 目录1. 基本定义与本质2. 内存管理3. 操作与功能4. 性能特点5. 使用场景6. 相互转换核心区别

Java中实现对象的拷贝案例讲解

《Java中实现对象的拷贝案例讲解》Java对象拷贝分为浅拷贝(复制值及引用地址)和深拷贝(递归复制所有引用对象),常用方法包括Object.clone()、序列化及JSON转换,需处理循环引用问题,... 目录对象的拷贝简介浅拷贝和深拷贝浅拷贝深拷贝深拷贝和循环引用总结对象的拷贝简介对象的拷贝,把一个

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

使用Java读取本地文件并转换为MultipartFile对象的方法

《使用Java读取本地文件并转换为MultipartFile对象的方法》在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求,在这种场景下,MultipartFile对象非... 目录1. 基本需求2. 自定义 MultipartFile 类3. 实现代码4. 代码解析5. 自定

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数