C++类与对象入门实践(日期类的实现)
日期类
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++类与对象入门实践(日期类的实现)相关推荐
- 10、类和对象:使用日期类计算相隔天数
问题描述 : 现有日期类Date.Date类定义如下: class Date{ int year; int month; int day; public: Date(int y,int m,int d ...
- 类与对象(一)----什么是类和对象
类 类在java语言中是一个数据类型,以class关键词+类名表示.是一个模糊的概念. 类在生活中可以这样理解: 猫是一个类:猫类(class Cat) 猫有品种:田园猫 布偶猫 金渐层 - 猫有年龄 ...
- 装饰器/使用类和对象封装一个工具类
# coding:utf-8 # 装饰器是以@开头,@结构称为语法糖,装饰器的作用主要是给现有的函数增加一些额外的功能. # @classmethod # @staticmethod # @prope ...
- 设计如下类: 1) 建立一个Point类,表示平面中的一个点;建立一个Line类,表示平面中的一条线端, 内含两个Point类的对象;建立Triangle类,表示一个三角形
设计如下类: 1) 建立一个Point类,表示平面中的一个点:建立一个Line类,表示平面中的一条线端, 内含两个Point类的对象:建立Triangle类,表示一个三角形,内含三个L ...
- 类和对象(一)——类对象概念及定义
c++是基于面向对象的语言,并不是纯面向对象的语言,因为它包含c的部分,c是面向过程的语言 一.面向对象 概念:面向对象程序设计(OOP)是一种程序设计的泛型,同时也是一种程序开发的方法,它将对象作为 ...
- C#类与对象_创建玩家类
C#:类与对象_创建玩家类,实现字段,方法,引用和简单游戏逻辑 //创建CF当中的玩家类Player,该类含有字段:名字,性别, 血量,武器. //武器背包当中匕首,步枪,机枪,狙击枪. 玩家类具有以 ...
- 【C++从入门到踹门】第三篇:类和对象(中)类的默认成员函数
目录 1.类的默认成员函数 2.构造函数 2.1 构造函数引入 2.2 构造函数概念及特点 3. 析构函数 3.1 析构函数引入 3.2 析构函数的概念 3.3 在哪些情况下会程序会执行析构函数? 3 ...
- 3-1:类与对象入门——类的引入和类的定义以及访问限定符和封装还有对面向对象的理解
文章目录 一:面向对象与面向过程 二:类的引入 三:类的定义 (1)C++类的定义 (2)类的两种定义方式 A:声明和定义全部放在类体中 B:定义和声明分开放 四:类的访问限定符及封装 (1)访问限定 ...
- oop 类和对象的_实用程序类的OOP替代
oop 类和对象的 实用程序类(也称为帮助程序类)是仅具有静态方法且不封装状态的"结构". StringUtils , IOUtils , FileUtils从Apache的共享 ...
最新文章
- 针对七牛含有特殊字符的文件名,对特殊字符编码处理
- msysGit 中文环境配置及跨平台开发注意事项
- visual studio2019许可证
- python调用摄像头转向_教你如何利用python调用摄像头
- 越是被吐槽,女博士这个群体就越强!!
- CentOS 7 搭建RAP2r Api文档管理系统
- 基于Java jsp+mysql+Spring的汽车出租平台租赁网站平台设计和实现
- java基础——构造函数小知识点
- java代码生成器_java代码生成器怎么用
- CentOS发行版本介绍
- java nginx 重启吗_Nginx的启动、停止、平滑重启
- 怎么看so文件是哪个aar引进来的_突破微信限制,超大文件可以随便发
- 惯性组合导航原理—[1] 方向余弦矩阵
- AutoLine源码之RobotFramework运行器
- 揭秘骗术:黑客人肉、查开房的灰色项目
- Windows Phone7屏幕方向与常用控件
- 欧拉φ函数和欧拉降幂公式
- 数据结构:网上公开课
- JSONObject、JSONArray
- 2022新版彩虹易支付系统源码/运营版/支持当面付/通道轮询/16支付插件/免签约支付系统