Hello,一只爱学习的鱼

  大学学习C++运算符重载的时候,老师出了一道“运算符重载+类”的综合练习题,让我们来一起看看吧!

  题目:  

  设计一个日期类Date,包括年、月、日等私有成员;

  要求实现基本运算:如一个日期加上天数,一个日期减去天数、两个日期相差天数。

  基本设计思路及要求:

  1.在Date类中设计如下重载运算符函数:

  Date operator+(int days); 返回一个日期加上一个天数得到的日期;

  Date operator-(int days); 返回一个日期减去一个天数得到的日期;

  int operator-(Date &b); 返回两日期相差的天数。

  2.在实现这些重载运算符函数调用以下私有成员函数:

  leap(int); 判断指定的年份是否为闰年;

  transDate(Date &); 将指定日期转换为从0年0月0日起的天数;

  transDay(int); 将指定的0年0月0日起的天数转换为对应的日期。

  3.在main( )中,实现日期的基本运算:

  (1).闰年与非闰年的判断,以及各月的天数的获得问题,解决办法可设置并引用二维数组;

  (2).日期基本问题的实现问题,解决办法是在Date类中设计重载运算符函数:Date operator+(int days)、Date operator-(int days)、int operator-(Date &b),同时调用以下私有成员函数leap(int)、transDate (Date &)、transDay (int)得以实现;

  (3).如何使输入的日期有效,如2011 13 34为无效日期,解决办法是在input()中设置判断条件if(month>12||month<1||day>day_tab[leap(year)][month-1]||year<=0),判断日期是否为有效日期。

  流程图:

  

  根据要求先写出类:

 1 #include <iostream>
2 using namespace std;  
3 bool datetime(int, int, int);    //使用自定义函数datetime判断输入的日期是否合法,合法返回1,不合法返回0
4 class Date {
5 public:
6 void input();
7 void output();
8 Date operator+(int days);
9 Date operator-(int days);
10 int operator-(Date& b);
11 private:
12 int leap(int);
13 int transDate(Date&);
14 int year, month, day;
15 }; 

  然后,完整代码,我写了317行。鉴于篇幅,我讲解重载运算符函数Date operator+(int days),获取完整代码请关注我的公众号(一只爱学习的鲤鱼),回复:1207运算符重载,即可。

 1 Date Date::operator+(int days) {
2 int y = this->year, m = this->month, d = this->day;
3 while ((leap(y) == 1 && transDate(*this) + days > 366 && days > 366) || (leap(!y) == 1 && transDate(*this) + days > 365) && days > 365)    //简化运算,当days>=365天,直接操作年份,没必要操作月份
4 {
5 y++;
6 if (leap(y) == 1)
7 days = days - 366;
8 else if (!leap(y) == 1)
9 days = days - 365;
10 }
11 continue_: while (((m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) && (days > 31))    //使用了goto语句,当days<365天,操作月份,每轮对月份运算一次,直至days小于当月天数
12 || ((m == 4 || m == 6 || m == 9 || m == 11) && (days > 30))
13 || (m == 2 && days > 29 && leap(y)) || (m == 2 && days > 28 && !leap(y))) {
14 if (m == 1) {
15 m = 2; days = days - 31;    //月份自增,days减去当月的天数
16 goto continue_;
17 }
18 if (m == 2) {
19 if (leap(y)) { m = 3; days = days - 29; }
20 else { m = 3; days = days - 28; }
21 goto continue_;
22 }
23 if (m == 3) {
24 m = 4; days = days - 31;
25 goto continue_;
26 }
27 if (m == 4) {
28 m = 5; days = days - 30;
29 goto continue_;
30 }
31 if (m == 5) {
32 m = 6; days = days - 31;
33 goto continue_;
34 }
35 if (m == 6) {
36 m = 7; days = days - 30;
37 goto continue_;
38 }
39 if (m == 7) {
40 m = 8; days = days - 31;
41 goto continue_;
42 }
43 if (m == 8) {
44 m = 9; days = days - 31;
45 goto continue_;
46 }
47 if (m == 9) {
48 m = 10; days = days - 30;
49 goto continue_;
50 }
51 if (m == 10) {
52 m = 11; days = days - 31;
53 goto continue_;
54 }
55 if (m == 11) {
56 m = 12; days = days - 30;
57 goto continue_;
58 }
59 if (m == 12) {
60 y++; m = 1; days = days - 31;
61 goto continue_;
62 }
63 }
64 if (m == 1 && d + days > 31) { m = 2; d = d + days - 31; }    //最后,操作号数
65 else if (m == 2 && d + days > 29 && leap(y)) { m = 3; d = d + days - 29; }
66 else if (m == 2 && d + days > 28 && !leap(y)) { m = 3; d = d + days - 28; }
67 else if (m == 3 && d + days > 31) { m = 4; d = d + days - 31; }
68 else if (m == 4 && d + days > 30) { m = 5; d = d + days - 30; }
69 else if (m == 5 && d + days > 31) { m = 6; d = d + days - 31; }
70 else if (m == 6 && d + days > 30) { m = 7; d = d + days - 30; }
71 else if (m == 7 && d + days > 31) { m = 8; d = d + days - 31; }
72 else if (m == 8 && d + days > 31) { m = 9; d = d + days - 31; }
73 else if (m == 9 && d + days > 30) { m = 10; d = d + days - 30; }
74 else if (m == 10 && d + days > 31) { m = 11; d = d + days - 31; }
75 else if (m == 11 && d + days > 30) { m = 12; d = d + days - 30; }
76 else if (m == 12 && d + days > 31) { y++; m = 1; d = d + days - 31; }    //注意!this->day加days超过了31,年份要自增
77 else d = d + days;
78 this->month = m;
79 this->year = y;
80 this->day = d;
81 return *this;    //返回this对象
82 }

  代码注释,写明我的编程思路和在编程中遇到的坑。(附:养成写代码注释,也是一种好习惯哦!)

  下面是我在Visual Studio 2019的运行结果:

  

  关注我的公众号(一只爱学习的鲤鱼)

  

  回复:1207运算符重载。即可得到运算符重载+日期类Date.cpp文件

  

  最后,也欢迎C++大佬,在评论区或公众号提出其他的解题思路,我们下期再见。

运算符重载+日期类Date的更多相关文章

  1. C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对运算符重载的函数有两种处理方式:(1)把运算符 ...

  2. 日期类 Date

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; impor ...

  3. C++走向远洋——49(项目一2、复数类中的运算符重载、类的友元函数)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  4. C++走向远洋——48(项目一1、复数类中的运算符重载、类的成员函数)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  5. C# 类型运算符重载在类继承中的调用测试

    这是一篇晦涩难懂的片面的研究 一,简单的继承层次 class CA { } class CB : CA{ } class CC : CB{ } } void Test(CA oa){//CATest ...

  6. C++学习6-面向对象编程基础(运算符重载、类的派生与继承、命名空间)

    运算符重载 重载的运算符是具有特殊名字的函数:它们的名字由关键字operator和其后要定义的运算符号共同组成.重载的运算符是遵循函数重载的选择原则,根据不同类型或不同参数来选择不同的重载运算符. 运 ...

  7. 日期类Date

    Java在日期类中封装了有关日期和时间的信息,用户可以通过调用相应的方法来获取系统时间或设置日期和时间.Date类中有很多方法在JDK1.0公布后已经过时了,在8.3中我们将介绍JDK1.0中新加的用 ...

  8. Java基础——日期类Date

    一.概述 date代表一个特定的时间,精确到毫秒 二.构造方法 方法名 说明 public Date() 分配一个Date对象,并初始化,以便它代表被分配的时间,精确到毫秒 public Date(l ...

  9. Java:日期类Date与Calendar

    Timestamp类型与日期类型之间的转化? Timestamp timestamp = Timestamp.valueOf("2017-03-17 07:00:00"); Dat ...

随机推荐

  1. Go语言核心36讲(Go语言进阶技术十)--学习笔记

    16 | go语句及其执行规则(上) 我们已经知道,通道(也就是 channel)类型的值,可以被用来以通讯的方式共享数据.更具体地说,它一般被用来在不同的 goroutine 之间传递数据.那么 g ...

  2. JAVA笔记4__static关键字/对象数组/foreach/方法的可变参数

    /** * static关键字:修饰属性(实质就是全局变量).方法(无需本类的对象即可调用此方法).类. * 1.static方法只能调用static方法 * 2.static方法只能访问static ...

  3. python教程-(四)当索引行不通时(python字典)

    一.创建和使用字典 1.函数dict #字典表示方式如下 >>> phonebook = {'tom':'18616271234',"Jim":"186 ...

  4. AC-DCN ESXi

    传统IT架构中的网络,根据业务需求部署上线以后,如果业务需求发生变动,重新修改相应网络设备(路由器.交换机.防火墙)上的配置是一件非常繁琐的事情.在互联网/移动互联网瞬息万变的业务环境下,网络的高稳定 ...

  5. JMH 使用指南

    简介 JMH(Java Microbenchmark Harness)是用于代码微基准测试的工具套件,主要是基于方法层面的基准测试,精度可以达到纳秒级.该工具是由 Oracle 内部实现 JIT 的大 ...

  6. Linux系统编程之进程控制(进程创建、终止、等待及替换)

    进程创建 在上一节讲解进程概念时,我们提到fork函数是从已经存在的进程中创建一个新进程.那么,系统是如何创建一个新进程的呢?这就需要我们更深入的剖析fork函数. 1.1 fork函数的返回值 调用 ...

  7. OpenHarmony LiteOS C-SKY指令集移植指北

    摘要:本文介绍在OpenHarmony社区LiteOS-M项目中新增C-SKY指令集的开发流程,以及适配相应qemu工程的方法和步骤,供LiteOS内核相关开发者学习交流. 本文分享自华为云社区< ...

  8. 一.Promise入门准备阶段

    一.Promise入门准备阶段 1.区别实例对象呵函数对象 2.两种类型的回调函数(同步与异步) 2.1 同步回调 2.2 异步回调 3.JS的error处理 3.1 错误的类型 3.2 错误处理与错 ...

  9. Azure Virtual NetWoker(一)对等互连网络

    一,引言 Virtual NetWork Peering 可以无缝连接两个 Azure Virtual NetWork,Virtual NetWork Peering 直接的网络流量是专用的.在实际项 ...

  10. Spark中资源调度和任务调度

    Spark比MR快的原因 1.Spark基于内存的计算 2.粗粒度资源调度 3.DAG有向无环图:可以根据宽窄依赖划分出可以并行计算的task 细粒度资源调度 MR是属于细粒度资源调度 优点:每个ta ...