当前位置: 首页 > news >正文

类与对象 -- 日期类实现

我们要结合之前学习的类的默认成员函数来实现一个简单的日期类

#pragma once
#include<iostream>
using namespace std;
#include<assert.h>class Date
{//流插入和流提取重载声明为友元,可以直接访问私有成员变量friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);private:int _year;int _month;int _day;public://默认构造函数Date(int year = 1900,int mouth = 1,int day = 1);//void print() const;   //这种不需要值变的直接声明为const成员函数//写一个函数查询每个月的天数,声明在类内默认内联,因为要频繁调用int GetMouthDay(int year,int mouth){//1.首先确保月份数合法assert(mouth > 0 && mouth <13);//2.使用静态数组保存每个月的天数//使用静态是因为只用初始化一次,要是不使用static,则每次调用都需要创建初始化这个数组,因为函数栈帧结束就会销毁,需要重新构建//适用场景:这种直接调用的数据,static保证了生命周期也保证了内存的节省static int mouthDayArray[13] = {-1,31,28,31,30,31,30,31,31,30,31,30,31};//首个元素设置为-1,这样契合从一月开始的语言逻辑//3.闰年判断,来改变闰年2月的天数if(mouth == 2 && ((year % 4 == 0 && year % 100 != 0 ) || (year % 400 == 0))){return 29;}else {return mouthDayArray[mouth];}}bool checkDate();   //检查日期合法性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;// d1 += 天数Date& operator+=(int day);Date operator+(int day) const;// d1 -= 天数Date& operator-=(int day);Date operator-(int day) const;// d1 - d2int operator-(const Date& d) const;// ++d1 -> d1.operator++()Date& operator++();// d1++ -> d1.operator++(0)// 为了区分,构成重载,给后置++,强⾏增加了⼀个int形参// 这⾥不需要写形参名,因为接收值是多少不重要,也不需要⽤// 这个参数仅仅是为了跟前置++构成重载区分Date operator++(int);Date& operator--();Date operator--(int);   //与++实现思路一致};// 重载
ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);
#include"Date.h"//检查日期是否合法
bool Date::checkDate()   //普通成员函数隐式传this作为首个参数
{if(_month < 1 || _month > 12 || _day < 1 || _day > GetMouthDay(_year,_month)){return false;}else{return true;}
}//重写构造函数
Date::Date(int year,int mouth,int day)
{_year = year;_month = mouth;_day = day;if(!checkDate()){cout << "日期非法" << endl;}
}void Date::print()const
{cout << _year << "-" << _month << "-" << _day << endl;
}//d1 < d2
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){return _day < d._day;}}return false;
}bool Date::operator==(const Date& d) const
{return _year == d._year&& _month == d._month&& _day == d._day;
}//d1 <= d2
bool Date::operator<=(const Date& d) const
{return *this < d || *this == d;
}bool Date::operator>(const Date& d) const
{return !(*this <= d);
}
bool Date::operator>=(const Date& d) const
{return !(*this < d);
}
bool Date::operator!=(const Date& d) const
{return !(*this == d);
}//给日期加上一个天数,返回加后的日期本身
Date& Date::operator+=(int day)
{if(_day < 0){return *this -= -_day;}_day += day;while(_day > GetMouthDay(_year,_month)) //while可以多次判断直到满足位置{_day -= GetMouthDay(_year,_month);_month++;if(_month == 13){++_year;_month = 1;}}return *this;
}Date Date::operator+(int day)const
{Date tmp = *this;tmp += day;return tmp;
}//这里-=和- 与上两个类似就不实现了//重载后置++
Date Date::operator++(int)   //这里的传参是与前置++区分,无实际意义
{Date tmp(*this);*this += 1;return tmp;
}//重载前置++
Date& Date::operator++()
{*this += 1;return *this;
}//前置后置--与++实现逻辑一致//重载对象相减d1 - d2
int Date::operator-(const Date& d)const
{//有两种可能,d1大或者d2大//默认一下初始大和小Date max = *this;Date min = d;       int flag = 1;   if(max < min){max = d;min = *this;flag = -1;}int n = 0;while(min != max){++min;++n;}return n * flag;
}//重载流插入运算符
//需要契合操作习惯   cout << " " << endl;
ostream& operator<<(ostream& out,const Date& d)
//返回引用的目的是直接改变原值而不是改变拷贝,而且本身就无法被拷贝
//返回类型是标准输出流类型,传的参数是cout的别名,因为需要链式访问,所以传引用返回
//第二个参数是类对象引用
//声明为友元是要访问私有成员变量
{out << d._year << "年" << d._month << "月" << d._day << "日" <<endl;return out;
}istream& operator>>(istream& in ,Date& d)
{cout << "请依次输入年月日>:" ;in >> d._year >> d._month >> d._day;//输入当然还要检查是否合法if(!d.checkDate()){cout << "日期非法 " <<endl;}return in;
}

主要注意的是流插入和流提取的重载,里面包含了传引用返回的思想,已经传引用返回实现链式访问,就可以连续调用重载的运算符了。

总结:

  1. bool operator<(const Date& d) const; // 不修改对象状态 这种不需要修改成员变量的函数,给后面加const保证安全性,且允许const对象调用
    
  2. // 复合赋值运算符:返回引用
    Date& operator+=(int day);// 算术运算符:返回新对象  
    Date operator+(int day) const;// 比较运算符:返回bool
    bool operator<(const Date& d) const;
  3. // 前置++:返回引用
    Date& operator++() {*this += 1;return *this;
    }// 后置++:返回临时对象,int参数用于区分
    Date operator++(int) {Date tmp(*this);*this += 1;return tmp;
    }

  4. 友元函数的合理使用
    friend ostream& operator<<(ostream& out, const Date& d);
    friend istream& operator>>(istream& in, Date& d);流操作符需要访问私有成员,必须声明为友元友元打破了封装,但要谨慎使用

  5. 重载cout cin的链式调用
    ostream& operator<<(ostream& out, const Date& d) 
    {out << d._year << "年" << d._month << "月" << d._day << "日";return out;  // 返回引用支持链式调用
    }返回流引用(ostream&)支持连续输出

  6. 对象声明周期的管理
    Date Date::operator+(int day) const 
    {Date tmp = *this;  // 创建临时对象tmp += day;return tmp;        // 返回临时对象
    }//传引用返回会出问题哦

http://www.dtcms.com/a/475585.html

相关文章:

  • 网站一键生成wapwordpress模板安装
  • 新能源网站建设哪家好门户网站建设要多少钱
  • 网站风格 颜色搭配美橙网站建设经典案例
  • 网站功能建设特点广西壮族自治区市场监督管理局
  • 【Bean】条件装配与动态注册
  • 做厨具公司网站广州开发网站
  • 网站建设编程时注意事项网站设计开发制作
  • Python datetime 教程
  • 浙江做铁塔的公司网站漯河网页制作
  • windows8风格网站模板上海高端室内设计公司
  • 网站设计公司北京服务类网站免费建站
  • 外贸网站建设视频教程网站建设免费教程
  • core-service systemd-random-seed.service(1)
  • 【复习】计网每日一题1005---物理层接口特性
  • 【系统分析师】经典习题:法律法规与标准化
  • 网站建设 数据库管理创新网站设计
  • Deep SORT:基于深度关联度量的简单在线实时跟踪
  • 12306网站很难做吗蒙古文网站建设
  • 杭州建网站的公司企业内部网站建设教程
  • 织梦网站如何做二级导航有网站代码怎么做网站
  • 网络建设的网站十大进销存管理软件
  • 最新电大网站开发维护静态html转wordpress
  • 免费建网站软件家具制作网站
  • 企业网站内容运营方案案例关于网站建设的方案ppt
  • 设计专业网站公司自助网站免费建站平台
  • 四川省的住房和城乡建设厅网站首页基于营销导向的企业网站建设研究
  • (CVPR 2025 最佳论文)【源码复现】VGGT: Visual Geometry Grounded Transformer”
  • 网站策划书包括哪些内容全国响应式网站建设
  • 抵押网站建设方案wordpress 短代码插件
  • 做调查的网站知乎wordpress 上传到域名