日期类的实现

news/2024/4/25 16:29:39/文章来源:https://blog.csdn.net/qq_54717101/article/details/127501883

前言:实现一个完整的日期类,来加强对这类的6个默认成员函数的认识。

目录

 构造函数

GetMonthDay函数中的三个细节:

打印函数

日期 += 天数

日期 + 天数

日期 -= 天数

日期 - 天数 

前置 ++

后置 ++

前置 -- 

 后置 -- 

日期类的大小关系比较 

>运算符的重载

==运算符的重载 

<运算符的重载

>=运算符的重载

 <=运算符的重载

!=运算符的重载

日期 - 日期

今天星期几 


日期类中所包含的成员函数和成员变量:

class Data
{
public:
    //构造函数
    Data(int year = 0, int month = 1, int day = 1);

    //赋值运算符的重载
    Data& operator=(const Data& d);

    //+=运算符的重载
    Data& operator+=(int day);
    //获得此年此月的天数
    int GetMonthDay(int year, int month)const;
    
    //+运算符的重载
    Data operator+(int day)const;

    //前置++重载
    Data& operator++();

    //后置++重载
    Data operator++(int);

    //-=运算符的重载
    Data& operator-=(int day);

    //-运算符的重载
    Data operator-(int day)const;

    //重载前置--

    Data& operator--();

    //后置--重载
    Data operator--(int);

    //>运算符重载
    bool operator>(const Data& d)const;

    //运算符==重载
    bool operator==(const Data& d)const;

    //运算符>=重载
    bool operator<=(const Data& d)const;

    //运算符<重载
    bool operator<(const Data& d)const;

    //运算符<=重载
    bool operator>=(const Data& d)const;

    //运算符!=重载
    bool operator!=(const Data& d)const;

    //日期-日期
    int operator-(const Data& d)const;

    //今天是星期几
    void IsWeekDay()const;

    //打印日期
    void Print()const;
   
private:
    int _year;
    int _month;
    int _day;
};
析构,拷贝构造,赋值重载可以不写,使用默认生成的即可

 构造函数

对象创建时,进行对象变量的赋值,需要先判断日期是否合理,进行后续构造。

因为函数声明(.h)与定义(.cpp)分离,所以定义需要指定函数的类域 类名::+函数名

int Data::GetMonthDay(int year, int month)const
{

     //数组存储平年每个月的天数
    const int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
    int day = days[month];
    if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
    {
        day += 1;//闰年二月的天数是29
    }
    return day;
}

Data::Data(int year, int month, int day)
{

     //判断日期是否合理之后进行赋值
    if (year >= 0 &&

       month > 0 && month < 13

       && day>0 && day <= GetMonthDay(year, month))
    {
        _year = year;
        _month = month;
        _day = day;
    }
    else
    {
        cout << "日期非法:";
        cout << _year << "-" << _month << "-" << _day << endl;
    }
}

GetMonthDay函数中的三个细节

1.用const修饰this指针,因为this不能被修改。

2.days数组最好用static修饰,这样在静态区存储,不会因为频繁调用而频繁创建。

3.判断平年还是闰年的天数时,先判断是否是二月,在进行平闰年的判断。

注:当函数声明和定义分开时,在声明时注明缺省参数,定义时就不能标出缺省参数。

打印函数

void Data::Print()const
{
    cout << _year << "年" << _month << "月" << _day << "日" << endl;
}

日期 += 天数

+=操作符,会改变对象变量的值。

实现思路:1.日期对象的天数加上天数  2.判断日期是否合理,若不合理(表示日满),天数-=这年这月的天数,然后月份month++,若month>12时,year++,month重新赋值为1(表示年满)。步骤2继续,直到日期合理为止。

Data& Data::operator+=(int day)
{
    if (day < 0)//这里表示+=的天数是一个负数,复用-=操作符
    {
        *this -= -day;
    }
    else
    {
        _day += day;
        while (_day > GetMonthDay(_year, _month))//不合理的日期继续执行
        {
            _day -= GetMonthDay(_year, _month);
            _month++;
            if (_month > 12)
            {
                _year++;
                _month = 1;
            }
        }
    }
    return *this;//this不会因为函数结束而销毁,可以用引用做返回值。
}

日期 + 天数

实现+,我们可以直接复用+=,但是需要注意,这个日期本身不会改变,例如:ret=i+1,i本身的值不会变。

Data Data::operator+(int day)const//this不会改变,用const修饰
{
    Data ret(*this);//利用this拷贝构造需要返回改变的ret
    ret += day;
    return ret;//ret出了函数作用域销毁,不可引用做返回值
}

日期 -= 天数

实现思路:1.日期对象的天数减上该天数  2.判断日期是否合理,若不合理,月份month--,day+=此年此月的天数,若month<1(表示该年已完) ,month=12,year--。继续执行步骤2,直到日期合理为止。

Data& Data::operator-=(int day)
{
    if (day < 0)//表示减一个负数,相当于+这个数的正数
    {
        *this += -day;//复用+=
    }
    else
    {
        _day -= day;//步骤1
        while (_day <= 0)//步骤2
        {
            _month--;
            if (_month < 1)
            {
                _year--;
                _month = 12;
            }
            _day += GetMonthDay(_year, _month);
        }
    }
    return *this;
}

日期 - 天数 

与+一样,我们复用-=,同样需要注意的问题和+的重载一样

Data Data::operator-(int day)const
{
    Data ret(*this);
    ret -= day;
    return ret;
}

前置 ++

一样可以复用+=,对象日期+1

Data& Data::operator++()
{
    *this += 1;
    return *this;//出了函数作用域,this不会销毁,引用做返回值
}

后置 ++

由于前置++和后置++的运算符均为++,为了区分它们的运算符重载,我们给后置++的运算符重载的参数加上一个int型参数,无需传实参,只是为了构成重载。

Data Data::operator++(int)
{
    Data ret(*this);
    *this += 1;
    return ret;
}

后置++也是需要返回加了之前的值,只能先用对象ret保存之前的值,然后对象日期加一,最后返回ret对象,ret出了函数作用域,销毁,不能引用做返回值

前置 -- 

可以复用-=,其他需要注意的和++一样

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

 后置 -- 

Data Data::operator--(int)
{
    Data ret(*this);
    *this -= 1;
    return ret;
}

日期类的大小关系比较 

日期类比较有六个(>   <   ==    !=   >=   <=),但是我们只需要实现两个,其他复用便可。

注:日期比较大小,说明本身都不会改变,都需要用cosnt修饰。

>运算符的重载

bool Data::operator>(const Data& d)const
{

    return _year > d._year || _month > d._month || _day > d._day;
}

==运算符的重载 

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

<运算符的重载

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

>=运算符的重载

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

 <=运算符的重载

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

!=运算符的重载

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

日期 - 日期

返回的是两个日期间隔的天数。

实现思路:让小的那个日期不断加1,也用一个count记录一下小的加1的次数,直到与大的那个相等,结束,此时count就是两个日期间隔天数。

若是第一个日期大于第二个日期,则返回这个差值的正值,若第一个日期小于第二个日期,则返回这个差值的负值。

int Data::operator-(const Data& d)const
{
    Data max = *this;
    Data min = d;
    int flag = 1;
    int count = 0;


    if (max < min)
    {
        max = d;
        min = *this;
        flag = -1;
    }


    while (max != min)
    {
        count++;
        min++;
    }
    return count*flag;
}
 

今天星期几 

1900,1,1是参考日期星期一,用需要判断星期几的日期-这个参考日期得到间隔天数,一周是7天,用得到的间隔天数%7(取值在0-6之间),就能得到星期几。

void Data::IsWeekDay()const
{
    int day=*this - Data(1990,1,1);//匿名对象生命周期就在这一行
    const char* days[7] = {"星期一","星期二", "星期三", "星期四", "星期五", "星期六", "星期天" };
    cout << days[day % 7] << endl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_218431.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业推进数字化转型零信任是必须?

随着企业数字化转型的深入&#xff0c;各企业的网络结构日趋复杂并且向云转化&#xff0c;以往基于边界的网关型身份和访问控制体系难以应对新型威胁&#xff1b;网络接入模式也更加多元化&#xff0c;移动办公、远程接入、云服务等场景在后疫情时代成为新常态&#xff0c;这大…

五、Zabbix — 监控报警那点事儿

监控告警的分类&#xff1a; 邮件 个人邮箱或者企业邮箱&#xff0c;免费使用企业微信 — 告警应用&#xff08;机器人&#xff09; 需要企业微信&#xff0c;免费使用钉钉告警 阿里云服务&#xff0c;免费使用短信 收费…

【附源码】计算机毕业设计SSM校园快递代取系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

设计模式之命令模式(行为型)

1、命令模式定义 命令模式&#xff08;Command&#xff09;&#xff0c;将一个请求封装为一个对象&#xff0c;请求以命令的形式包裹在对象中&#xff0c;传递给调用对象&#xff0c;调用对象寻找可以处理该命令的合适的对象&#xff0c;并将命令传递给相应的对象&#xff0c;该…

creo草绘工程图标注字体大小、加粗设置

刚接触creo&#xff0c;字体又小又细&#xff0c;这的眼睛受不了&#xff01; 在网上找了很久&#xff0c;发现字体设置非常麻烦&#xff0c;我先是调整了字体的大小&#xff0c;但是字体很细&#xff0c;于是只能通过设置字体来改变粗细&#xff0c;实在找不到设置字体加粗的…

jenkins简介

参考链接&#xff1a;jenkins_L向上z的博客-CSDN博客_jenkins Jenkins详细教程_zhishidi的博客-CSDN博客_jenkins jenkins最主要的作用是什么&#xff1f; - 知乎 1.背景   在实际开发中&#xff0c;我们经常要一边开发一边测试&#xff0c;当然这里说的测试并不是程序员对…

golang-gin框架快速入门--推荐

1.设置golangd的配置&#xff1b; go env :命令后&#xff0c;获取安装gin的国内代理&#xff0c;解决访问国外网站下载包慢的问题 1.1.检查golangd的设置 检查上述三个地方的设置&#xff0c;看看是否正确&#xff0c;重点是工modules这个地方设置&#xff0c;查看是否启用了国…

git实用操作:git rebase -i 合并多个 commit

我们开发的过程中&#xff0c;可能会有多次的修补提交&#xff0c;就会出现多条提交记录和备注信息&#xff0c;此时我们可以使用 git rebase -i来合并多个commit&#xff0c;以简化提交记录 1.合并最近的 4 次提交纪录&#xff0c;执行&#xff1a; git rebase -i HEAD~42.自…

今天不想上班

无语 - - 为什么项目迁移了 算了 不需要脑子思考复杂的 反正我干就是了&#xff0c;领了工资干了活&#xff0c;我菜那是我的事。 顺便学习一下好了。 可能我基础不太行吧。 关于我和同事新一起合作写一个项目 老板让我优化代码后老板满意了同事被封装的痛苦了。 现在…

TortoiseSVN下载安装及问题总结

文章目录TortoiseSVN介绍下载安装问题使用首先将客户端与服务器进行连接检出提交TortoiseSVN介绍 TortoiseSVN是一个开源的版本控制系统&#xff0c;也就是说Subversion管理者随着时间而改变的数据。这些数据放置在任何一个中央资料档案库&#xff08;repository&#xff09;中…

中国定制家具行业深度调研及投资前景预测报告

欧派家居VS索菲亚:家具商业的布局史 家具产品的特性决定了家具产业在经济和社会中的重要地位。随着经济的不断发展&#xff0c;家具行业也发展迅速。目前&#xff0c;欧派家居和索菲亚是国内家具行业的龙头企业主。 2.家具企业布局及经营状况: ——家具经营类型:索菲亚、欧派…

Apollo星火计划学习笔记第四讲1——Apollo高精地图模块

Apollo学习笔记零、目录一、高精地图的作用1.1 相对于传统地图二、高精地图介绍2.1 高精地图构成2.2 高精地图制作2.2.1 地图采集2.2.2 地图制作2.2.3 地图标注工具2.2.4 地图保存三、Apollo高精度地图3.1 高精地图目录结构3.2 高精地图格式3.3 Apollo高精地图API接口四、实践案…

【Gateway】统一网关Gateway学习记录

目录 网关能干什么 网关的技术实现 搭建网关服务 网关作用流程图 路由断言工厂&#xff08;Route Predicate Factory&#xff09; gateway中有三种过滤器&#xff1a; 1. 默认过滤器&#xff08;DefaultFiter&#xff09; 2. 路由过滤器&#xff08;GatewayFilter&…

3. Longest Substring Without Repeating Characters (无重复字符的最长子串)滑动窗口

文章目录问题英文中文代码小白的码大佬的码知识点unordered_set 容器具有以下几个特性&#xff1a;总结问题 英文 3. Longest Substring Without Repeating Characters (无重复字符的最长子串) 中文 代码 小白的码 #include <iostream> #include <string> #…

Terraform 基础 申请阿里云资源

之前&#xff0c;资源都定义好了&#xff0c;现在就是去申请资源了。 申请这些资源就需要使用terraform的命令行了&#xff0c;开始初始化后端&#xff0c;后端是有存储文件的&#xff0c;默认情况下是在本地存储的&#xff0c;然后会多一些文件。 &#xff08;下载插件&#x…

在python中安装gensim包(为了使用LDA)

LDA是英文“Latent Dirichlet Allocation”的缩写&#xff0c;意思是隐含狄利克雷分布&#xff0c;是一种主题模型&#xff08;topic model&#xff09;&#xff0c;它可以将文档集中每篇文档的主题以概率分布的形式给出。 gensim包中有LDA的一种实现。 本文介绍gensim包的安…

神经网络中的算法-梯度下降算法

目录 一、概述 二、算法思想 1、一维 2、多维 三、梯度下降类型 1、批量梯度下降算法 2、随机梯度下降算法 3、小批量梯度下降算法 一、概述 梯度下降法&#xff08;Gradient descent &#xff09;是一个一阶最优化算法&#xff0c;通常也称为最陡下降法 &am…

NetworkManager nmcli ipv4 静态ip 笔记221025

nmcli connection modify 可以修改现有连接 con 可以写成 c 到 connection 之间的字段mod 可以写成 m 到 modify 之间的字段nmcli connection modify nmcli connec modify nmcli conne modif nmcii conn modi nmcli con mod nmcli co mo nmcli c m nmcli c modify nmcli conne…

购物中心智能管理系统该如何选择

快鲸智慧楼宇系统作为新一代数智化商管系统&#xff0c;以实际业务场景出发构建产品逻辑&#xff0c;并在传统商管系统基础上&#xff0c;拥有独家的商业大数据加持&#xff0c;同时嵌入了BI智能分析工具&#xff0c;打造了一个招商营运场景的数智化系统&#xff0c;将“人的经…

[C++] 初接触 泛型编程—— C++ 模板分析

泛型编程 C中引入了重载的概念&#xff0c;使得可以编写多个函数名相同但参数、返回值不同的函数&#xff0c;例如&#xff1a; 相同的函数名可以传入不同的参宿&#xff0c;进而调用不同的函数 但&#xff0c;即使有了重载&#xff0c;相同功能的函数 还要分别对不同的类型进…