日期类

class Date
{
public://成员函数private:int _year;int _month;int _day;
};

日期类成员对象:  年、月、日

实现功能:  成员函数

     即用四个默认成员函数就可以实现一个日期类。

1.构造函数

       实现日期年月日的初始化,函数包括年月日的初始化,传参(判断初始化当年是否为闰年,即获得当年2月具体的天数)

//获取某年具体的某一天
inline int GetMonthDay(int year, int month)  //写成内联函数,减少函数调用栈开销
{static int MonthDayArray[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};   //static 静态,保证数组中的天数不变if(month == 2&& ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){return 29;  //实现瑞年2月输出29天}else{return MonthDayArray[month];}
}
Date(int year = 1900, int month = 1, int day = 1)
{if(year >= 1900     //保证日期的合法性&& (month > 0 && month <= 13)&& day <= GetMonthDay(year, month)){_year = year;_month = month;_day = day;}else{cout << "非法日期!" << endl;}
}

2.析构函数

日期类的构造中没用开辟新空间,也没有打开文件等操作。因此使用系统的默认析构函数就够用

不需要自定义实现。

3.拷贝构造函数

日期类的拷贝构造,只用拷贝对象中的内容,即编译器默认实现的浅拷贝(按字节序依次拷贝)。

需要注意拷贝日期的const修饰,和函数参数传引用等问题。

Date(const Date& d)  //拷贝构造函数
{_year = d._year;_month = d._month;_day = d._day;
}Date d1(2019, 5, 12);Date d2;
d2(d1);

4.赋值运算符重载

      函数原型:返回值类型 operator操作符(参数列表)

在日期类中用来实现:日期加减天数、日期减日期、日期比较赋值等

  运算符重载可以写在全局中,也可写在类里面,一般建议写在类里面。使他们转换为内联函数,减少函数调用栈开销。

1) 日期加天数:实现 +=  就可利用此运算符重载实现 +    ++ 等运算符重载

思路: 日期+天数,利用循环  用日期的天数加上给定天数、判断日期天数大于本月的应有天数,则给月份加1、月份等于12时,年份加1,月份置为1,直到天数为本月合理天数结束返回。

Date& operator+=(int day)  //函数返回值带引用,表示返回值变量在出了函数作用域还在
{if(day < 0){   //日期小于0 则等于-正天数return *this -= -day;}_day += day;  //先把天数加起来while(_day > GetMonthDay(_year, _month))  //天数不合理{if(_month == 12){   //月到12   则年加1++_year;_month = 1;}++_month;_day -= GetMonthDay(_year, _month);  //天数减去这月正常的天数,再取判断}return *this;
}

2)日期减天数:实现 -=  就可利用此运算符重载实现 -    -- 等运算符重载

思路:日期减天天数,日期的天减去天数,循环判断日期天数是否小于等于0,月份减一,如果月份等于0,年份减一,月份置为12月

日期天数加上本月的合理天数再去判断。

Date& operator-=(int day)
{if(_day < 0){   //数天小于0return *this += -day;}_day -= day;while(_day <= 0)  //天数小于等于0进入循环{--_month;   //月份为1  年份减一if(_month == 0){--_year;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}

3)日期 - 日期:  返回两个日期相差的天数

思路:取两个日期变量,表示两个日期。  小日期++,直到等于大日期。用计数器days记录 并返回

int operator-(const Date& d)
{Date minDate(*this);Date maxDate(d);int flag = 1;if(minDate > maxDate){maxDate = *this;minDate = d;flag = -1;}int days = 0;while(minDate != maxDate){minDate += 1;++days;}return days * flag;
}

4) 日期间的比较:  boo类型返回值

实现 <   > 就可以根据运算符重载对 >取反就可实现 <=    >=   等

bool operator<(const Date& d) const
{if((_year < d._year)  //只要有一个小于就小于|| (_year == d._year && _month < d._month)|| (_year == d._year && _month == d._month && _day < d._day)){return true;}else{return false;}
}

日期类具体实现C++代码如下:

  成员函数建议都在写在类里面,默认内联。

此处的复制运算符重载,为测试程序没有写进类里。

Date.h

#include <iostream>using std::cout;
using std::endl;#pragma onceclass Date
{
public://构造函数:  初始化对象、函数名与类名相同、无返回值、对象实例化时系统自动调用//1.系统默认构造函数(没什么实际作用,自动调用后,初始化的对象还是随机值)/*Date(){   //无参构造函数_year = 1900;_month = 1;_day = 1;}*///2.用户自定义构造函数,通常构造函数还需要能判断日期的有效性//Date(int year = 1900, int month = 1, int day = 1)//{   //与上面构造函数构成重载,全缺省参数//    //一般推荐这种写法//    _year = year;//    _month = month;//  _day = day;//}//可返回某年某月具体有多少天inline int GetMonthDay(int year, int month){static int MonthArray[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))){   //瑞年的2月是29天return 29;}return MonthArray[month];}Date(int year = 1900, int month = 1, int day = 1){if (year >= 1900&& month > 0 && month < 13&& day > 0 && day <= GetMonthDay(year, month)){_year = year;_month = month;_day = day;}else{cout << "非法输入" << endl;}}//析构函数: 完成清理:如 malloc -> free   fopen -> fclose//1.析构函数名实在类名前加上字符~//2.无参数 无返回值//3.一个类只有一个析构函数,若未显示定义,系统会自动生成默认的析构函数//4.对象生命周期结束时,C++编译系统对自动调用析构函数。~Date(){   //每次对象结束时,编译系统都会自动调用析构函数cout << "析构函数调用" << endl;}//拷贝构造函数:创建相同的类对象、对构造函数传引用类型的对象,一般常用const修饰//1.拷贝构造函数时=是构造函数的一个重载形式//2.他的参数只用一个且必须使用引用传参,如果使用传值形式,会引发无穷递归调用//3.没有自定义时,系统自动生成默认的拷贝构造函数(默认按字节序完成拷贝)//    值拷贝/或浅拷贝Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}//赋值运算符重载//运算符重载:有特殊函数名的函数//函数原型:返回值类型+operator操作符(参数列表)//1.不能通过其他符号来创建新的操作符//2.重载操作符必须有一个类类型或者枚举类型的操作数//3.用于内置类型的操作符,其含义不能改变//4.作为类成员函数重载时,其形参看起来少一个,操作符有一个默认的形参this//5.  .*  ::   sizeof  ?:  .   五个运算符不能重载//运算符重载一般可以写成全局的,但需要成员变量为公有的//所以一般还是写在类里面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;Date& operator++();       //前置++Date operator++(int);    //后置++Date& operator--();       //前置--Date operator--(int);    //后置--Date operator+(int day) const;      Date operator-(int day) const;    Date& operator+=(int day);Date& operator-=(int day);    int operator-(const Date& d);void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};

Date.cpp

#include "Date.h"bool Date::operator>(const Date& d) const
{if (_year > d._year){return true;}else if (_year == d._year){if (_month > d._month){return true;}else if (_month == d._month){if (_day > d._day){return true;}}}return false;
}
bool Date::operator>=(const Date& d) const
{if (*this < d){return false;}else{return true;}
}
bool Date::operator<(const Date& d) const
{if (_year < d._year|| (_year == d._year && _month < d._month)|| (_year == d._year && _month == d._month && _day < d._day)){return true;}else{return false;}
}
bool Date::operator<=(const Date& d) const
{if (*this > d){return false;}else{return true;}
}
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 _year != d._year || _month != d._month || _day != d._day;
}Date& Date::operator+=(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++()      //前置++
{*this += 1;return *this;
}
Date Date::operator++(int)   //后置++
{Date ret(*this); //拷贝构造*this += 1;return ret;
}
Date Date::operator+(int day) const
{Date ret = *this;ret += day;return ret;
}Date& Date::operator--()         //前置--
{*this -= 1;return *this;
}
Date Date::operator--(int)     //后置--
{Date ret(*this);ret -= 1;return ret;
}
Date Date::operator-(int day) const
{Date ret = *this;ret -= day;return ret;
}
Date& Date::operator-=(int day)
{_day -= day;while (_day <= 0){if (_month == 1){_year--;_month = 12;}else{_month--;}_day += GetMonthDay(_year, _month);}return *this;
}int Date::operator-(const Date& d)  //两个日期相减
{Date maxDate(*this);Date minDate(d);int flag = 1;if (maxDate < minDate){flag = -1;maxDate = d;minDate = *this;}int days = 0;while (minDate != maxDate){minDate += 1;++days;}return days * flag;
}

main.cpp

#include "Date.h"//写测试程序
int main()
{Date d1(2019, 5, 13);d1.Print();Date d2;d2.Print();Date d3(d1);d3.Print();cout << d3 - d2 << endl;d3 += 18;d3.Print();d3 -= 10;d3.Print();(d2 + 10000).Print();return 0;
}

C++类与对象入门实践(日期类的实现)相关推荐

  1. 10、类和对象:使用日期类计算相隔天数

    问题描述 : 现有日期类Date.Date类定义如下: class Date{ int year; int month; int day; public: Date(int y,int m,int d ...

  2. 类与对象(一)----什么是类和对象

    类 类在java语言中是一个数据类型,以class关键词+类名表示.是一个模糊的概念. 类在生活中可以这样理解: 猫是一个类:猫类(class Cat) 猫有品种:田园猫 布偶猫 金渐层 - 猫有年龄 ...

  3. 装饰器/使用类和对象封装一个工具类

    # coding:utf-8 # 装饰器是以@开头,@结构称为语法糖,装饰器的作用主要是给现有的函数增加一些额外的功能. # @classmethod # @staticmethod # @prope ...

  4. 设计如下类: 1) 建立一个Point类,表示平面中的一个点;建立一个Line类,表示平面中的一条线端, 内含两个Point类的对象;建立Triangle类,表示一个三角形

    设计如下类:     1) 建立一个Point类,表示平面中的一个点:建立一个Line类,表示平面中的一条线端,     内含两个Point类的对象:建立Triangle类,表示一个三角形,内含三个L ...

  5. 类和对象(一)——类对象概念及定义

    c++是基于面向对象的语言,并不是纯面向对象的语言,因为它包含c的部分,c是面向过程的语言 一.面向对象 概念:面向对象程序设计(OOP)是一种程序设计的泛型,同时也是一种程序开发的方法,它将对象作为 ...

  6. C#类与对象_创建玩家类

    C#:类与对象_创建玩家类,实现字段,方法,引用和简单游戏逻辑 //创建CF当中的玩家类Player,该类含有字段:名字,性别, 血量,武器. //武器背包当中匕首,步枪,机枪,狙击枪. 玩家类具有以 ...

  7. 【C++从入门到踹门】第三篇:类和对象(中)类的默认成员函数

    目录 1.类的默认成员函数 2.构造函数 2.1 构造函数引入 2.2 构造函数概念及特点 3. 析构函数 3.1 析构函数引入 3.2 析构函数的概念 3.3 在哪些情况下会程序会执行析构函数? 3 ...

  8. 3-1:类与对象入门——类的引入和类的定义以及访问限定符和封装还有对面向对象的理解

    文章目录 一:面向对象与面向过程 二:类的引入 三:类的定义 (1)C++类的定义 (2)类的两种定义方式 A:声明和定义全部放在类体中 B:定义和声明分开放 四:类的访问限定符及封装 (1)访问限定 ...

  9. oop 类和对象的_实用程序类的OOP替代

    oop 类和对象的 实用程序类(也称为帮助程序类)是仅具有静态方法且不封装状态的"结构". StringUtils , IOUtils , FileUtils从Apache的共享 ...

最新文章

  1. 针对七牛含有特殊字符的文件名,对特殊字符编码处理
  2. msysGit 中文环境配置及跨平台开发注意事项
  3. visual studio2019许可证
  4. python调用摄像头转向_教你如何利用python调用摄像头
  5. 越是被吐槽,女博士这个群体就越强!!
  6. CentOS 7 搭建RAP2r Api文档管理系统
  7. 基于Java jsp+mysql+Spring的汽车出租平台租赁网站平台设计和实现
  8. java基础——构造函数小知识点
  9. java代码生成器_java代码生成器怎么用
  10. CentOS发行版本介绍
  11. java nginx 重启吗_Nginx的启动、停止、平滑重启
  12. 怎么看so文件是哪个aar引进来的_突破微信限制,超大文件可以随便发
  13. 惯性组合导航原理—[1] 方向余弦矩阵
  14. AutoLine源码之RobotFramework运行器
  15. 揭秘骗术:黑客人肉、查开房的灰色项目
  16. Windows Phone7屏幕方向与常用控件
  17. 欧拉φ函数和欧拉降幂公式
  18. 数据结构:网上公开课
  19. JSONObject、JSONArray
  20. 2022新版彩虹易支付系统源码/运营版/支持当面付/通道轮询/16支付插件/免签约支付系统

热门文章

  1. JavaScript中的骚操作
  2. Wireshark抓包定位系统网页响应慢的问题
  3. NetInside网络分析帮您解决系统性能问题(一)
  4. [LiteratureReview]PointNet Deep Learning on Point Sets for 3D Classification and Segmentation
  5. 偷盗钻石(Diamond)
  6. 1157 -- 茵茵的第一课
  7. MongoDB数据库—基本操作
  8. OpenWrt 安装 mDNS,并设置 mDNS 映射
  9. 人生必读的100本好书
  10. 企业不懂如何选择低代码平台?看看这20家优秀的厂商