当前位置:网站首页>Date类的实现
Date类的实现
2022-07-01 00:32:00 【百言灵都】
日期类的实现
Date.h
#pragma once
#include<iostream>
#include<assert.h>
using std::cout;
using std::cin;
using std::endl;
class Date
{
public:
void Print();
//1
//Date(const Date& d)
//{
// _year = d._year;
// _month = d._month;
// _day = d._day;
//}
//2
//Date& operator=(const Date& d)
//{
// if (this != &d)
// {
// _year = d._year;
// _month = d._month;
// _day = d._day;
// }
// return *this;
//}
//判断闰年
bool LeapYear(int year)
{
if ((year % 4 == 0) && (year % 100 != 0))
return true;
if (year % 400 == 0)
return true;
return false;
}
//获取任意一个月份的天数
int GetMonthDay(int year, int month)
{
assert(year >= 0 && month > 0 && month < 13);
const static int day[13] = {
0,31,28,31,30,31,30,31,31,30,31,30,31 };
if (LeapYear(year) && month == 2)
return 29;
return day[month];
}
//构造函数用于初始化
Date(int year=1 , int month=1 , int day=1 )
{
//判断时间的合法性
assert(year >= 1 && month >= 1 && month <= 12 && day >= 1 && day <= GetMonthDay(year, month));
_year = year;
_month = month;
_day = day;
}
Date operator+(int day);
Date operator-(int day);
int operator-(Date& d);
// 日期+=天数
Date& operator+=(int day);
// 日期-=天数
Date& operator-=(int day);
// 前置++
Date& operator++();
// 后置++
Date operator++(int);
// 后置--
Date operator--(int);
// 前置--
Date& operator--();
// >运算符重载
bool operator>(const Date& d);
// ==运算符重载
bool operator==(const Date& d);
// >=运算符重载
bool operator>= (const Date& d)
{
return (*this > d || *this == d);
}
// <运算符重载
bool operator<(const Date& d)
{
return !(*this >= d);
}
// <=运算符重载
bool operator <= (const Date& d)
{
return !(*this > d);
}
// !=运算符重载
bool operator != (const Date& d)
{
return !(*this == d);
}
private:
int _year;
int _month;
int _day;
};
//1
拷贝构造函数,在Date类的实现中,可以不写,但是如果要写的话,要注意参数应用const修饰(因为如果是 Date d2=d1+10; 这种情况,其中 d1+10 调用加法重载函数是值返回,实际上是d1+10拷贝给临时变量,临时变量再拷贝给d2,临时变量具有常属性,所以参数需要用const修饰)
//2
赋值重载函数,在Date类的实现中,可以不写,但是如果要写的话,要注意参数应用const修饰(与1同理)
Date.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"
void Date::Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
// 日期+=天数
Date& Date::operator+=(int day)
{
//1
if (day < 0)
return *this -= -day;
//2
_day += day;
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
_month++;
if (_month > 12)
{
_year++;
_month = 1;
}
}
//3
return *this;
}
// 日期-=天数
Date& Date::operator-=(int day)
{
//4
if (day < 0)
return *this += -day;
_day -= day;
while (_day <= 0)
{
_day += GetMonthDay(_year, _month);
_month--;
if (_month <= 0)
{
_month = 12;
_year--;
}
}
return *this;
}
//+天数
Date Date:: operator+(int day)
{
//5
Date tmp(*this);
//6
tmp += day;
return tmp;
}
//-天数
Date Date::operator-(int day)
{
//7
Date tmp(*this);
tmp -= day;
return tmp;
}
//-日期
int Date::operator-(Date& d)
{
//8
int flag = 1;
Date max(*this);
Date min(d);
if (*this < d)
{
min = *this;
max = d;
flag = -1;
}
int n = 0;
while (min != max)
{
min++;
n++;
}
return n * flag;
}
// 前置++
Date& Date::operator++()
{
//9
(*this) += 1;
return *this;
}
// 后置++
Date Date::operator++(int)
{
//10
Date tmp(*this);
(*this) += 1;
return tmp;
}
// 后置--
Date Date::operator--(int)
{
//11
Date tmp(*this);
(*this) -= 1;
return tmp;
}
// 前置--
Date& Date::operator--()
{
//12
(*this) -= 1;
return *this;
}
// >运算符重载
bool Date::operator>(const Date& d)
{
if ((_year > d._year) || (_year == d._year && _month > d._month) || (_year == d._year && _month == d._month && _day > d._day))
return true;
return false;
}
// ==运算符重载
bool Date::operator==(const Date& d)
{
if ((_year == d._year) && (_month == d._month) && (_day == d._day))
return true;
return false;
}
//1
在+=中,如果day为负数,就相当于-=正数
//2
day>=0,将day先加到*this的_day上,做一个循环,
判断天数是否超过当前月份天数,若超过,将*this._day减去当月天数,*this._month++,再判断月份是否超过12,若超过,*this._day=1,*this._year++。
直到*this._day合法,循环结束。
//3
+=重载函数采用引用返回,因为return *this,因为在这个函数域外,this指针指向的空间依旧存在,所以可以采用引用返回(引用返回相对于值返回,不需要拷贝(调用拷贝构造函数),效率更高一些)
//4
-=与+=同理
//5
-天数,需要保证*this的值不变
//6
+天数重载函数中,使用+=(不用实现+,而且+=是引用返回,效率更高)
//7
-天数与+天数同理
//8
-日期
设置一个flag判断*this与d相差天数的正负,两个Date类,max,min,max为较大的,min为较小的,设置n表示天数,一个循环,min++,n++直到min和max相等,再根据flag返回天数。
//9
在++中使用+=(不用再实现++),前置++是返回+1之后的值,返回*this,使用引用返回
//10
为了避免调用函数时发生歧义,后置++重载函数的参数需要int占位,后置++是返回+1之前的值,返回tmp,使用值返回
//11
与后置--同理
//12
与前置--同理
test.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"
void TestDate1()
{
Date d1(2022, 5, 18);
Date d2(2023, 3, 20);
Date d3(2023, 3, 20);
cout << (d1 < d2) << endl;
cout << (d1 > d2) << endl;
cout << (d1 == d3) << endl;
cout << (d2 <= d3) << endl;
cout << (d2 == d3) << endl;
}
void TestDate2()
{
Date d1(2022, 5, 18);
Date d2 = d1 + 15;//拷贝构造相当于Date d2(d1+15);
Date d3;
d3 = d1 + 15;//赋值重载
d2.Print();
d1.Print();
d1 += 15;
d1.Print();
}
void TestDate3()
{
Date d1(2022, 5, 18);
Date d2 = d1 - 30;
d2.Print();
d1 -= 30;
d1.Print();
Date d3(2022, 5, 18);
d3 += 10000;
d3.Print();
d3 -= 10000;
d3.Print();
}
void TestDate4()
{
Date d1(2022, 5, 18);
d1 -= -100;
d1.Print();
d1 += -100;
d1.Print();
Date d2(2022, 5, 18);
Date ret1 = ++d2; // d2.operator++()
ret1.Print();
d2.Print();
Date ret2 = d2++; // d2.operator++(0)
ret2.Print();
d2.Print();
}
void TestDate5()
{
Date d1(2022, 5, 18);
Date d2(2020, 2, 4);
cout << (d1 - d2) << endl;
cout << (d2 - d1) << endl;
}
void Func(Date& d)
{
d.Print(); // d1.Print(&d); -> const Date*
}
void TestDate6()
{
Date d1(2022, 5, 18);
d1.Print(); // d1.Print(&d1); -> Date*
Func(d1);
}
int main()
{
TestDate1();
TestDate2();
TestDate3();
TestDate4();
TestDate5();
TestDate6();
TestDate6();
return 0;
}
测试运行结果

const成员

在类中,成员函数都包含一个隐含的this指针
比如:上图中的成员函数显示写出来是:
void Print(Date* const this)//this指针本身不能变,但是this指针指向空间的内容可以改变
{
cout << _year << "-" << _month << "-" << _day << endl;
}
但是这可能会出现错误
void Func(const Date& d)
{
d.Print(); // d.Print(&d); -> const Date*
}
d.Print(); -> Print(&d) -> const Date*
在调用Print()时,实参是const Date*,但是Print()的形参是Date* const,权限放大,发生错误
如何解决?
c++为我们提供了一个方法:
void Print() const
显示写出来是:
void Print(const Date* const this)
{
cout << _year << "-" << _month << "-" << _day << endl;
}
建议在成员函数中不修改成员变量的成员函数都加上
const普通对象和
const对象都能调用
请思考下面的几个问题:
const对象可以调用非const成员函数吗?- 非
const对象可以调用const成员函数吗?const成员函数内可以调用其他的非const成员函数吗?- 非
const成员函数内可以调用其他的const成员函数吗?
- × 权限放大
- √ 权限缩小
- × 权限放大
- √ 权限缩小
边栏推荐
- Summer Challenge [FFH] harmonyos mobile phone remote control Dayu development board camera
- From January 11, 2007 to January 11, 2022, I have been in SAP Chengdu Research Institute for 15 years
- Ybtoj exchange game [tree chain splitting, line segment tree merging]
- Vmware16 installing win11 virtual machine (the most complete step + stepping on the pit)
- Bugku CTF daily one question dark cloud invitation code
- 20220216 misc buuctf backdoor killing (d shield scanning) - clues in the packet (Base64 to image)
- Pycharm useful shortcut keys
- 如何关闭一个开放的DNS解析器
- The difference between union and union all in MySQL
- The college entrance examination in 2022 is over. Does anyone really think programmers don't need to study after work?
猜你喜欢

1. crawler's beautifulsoup parsing library & online parsing image verification code

Bugku CTF daily one question dark cloud invitation code

left join左连接匹配数据为NULL时显示指定值

Unit test concept and purpose

Inventory the six second level capabilities of Huawei cloud gaussdb (for redis)

IFLYTEK active competition summary! (12)

20220215-ctf-misc-buuctf-ningen--binwalk analysis --dd command separation --archpr brute force cracking

什么是SRM系统,如何规范公司内部采购流程

2022-2028 global capsule shell industry research and trend analysis report

Confirm() method of window
随机推荐
2022-2028 global ultra high purity electrolytic iron powder industry research and trend analysis report
Rhai - rust's embedded scripting engine
Longest valid bracket
How to specify the number of cycles in JSTL- How to loop over something a specified number of times in JSTL?
Teach you how to use Hal library to get started -- become a lighting master
Software supply chain security risk pointing North for enterprise digitalization and it executives
女朋友说:你要搞懂了MySQL三大日志,我就让你嘿嘿嘿!
20220215 misc buctf easycap Wireshark tracks TCP flow hidden key (use of WinHex tool)
Techo youth 2022 academic year college open class: behind the live broadcast of Lianmai, explore how to apply audio and video technology
How to close an open DNS resolver
Random ball size, random motion collision
Redis - understand the master-slave replication mechanism
Deployment of mini version message queue based on redis6.0
CentOS installation starts redis
What is SRM system and how to standardize the internal procurement process of the company
Why did kubernetes win? The changes in the container circle!
Redis - cache penetration, cache breakdown, cache avalanche
2022-2028 global elevator emergency communication system industry research and trend analysis report
Matlab saves triangulation results as STL files
2022-2028 global plant peptone industry research and trend analysis report