地税网站如何做税种确认,网站的角色设置如何做,公司找人做的网站到现在还没出来,wordpress 淘宝分享插件下载类与对象的实践 项目背景项目需求项目实现1 日期结构设计2 构造函数2.1 全缺省构造函数2.2 拷贝构造函数2.3 析构函数 3 赋值运算符重载3.1 重载3.2 重载重载前置 和 后置 4 关系操作符重载5 工具方法5.1 计算日期差5.2 日期转换为字符串5.3 通过字符串构建对象 完整源代码Dat… 类与对象的实践 项目背景项目需求项目实现1 日期结构设计2 构造函数2.1 全缺省构造函数2.2 拷贝构造函数2.3 析构函数 3 赋值运算符重载3.1 重载3.2 重载重载前置 和 后置 4 关系操作符重载5 工具方法5.1 计算日期差5.2 日期转换为字符串5.3 通过字符串构建对象 完整源代码Date.hDate.cpp Thanks♪(ω)谢谢阅读下一篇文章见 根据我们对C特性的学习我们现在可以尝试下一些新玩法来强化我们对C的理解。
项目背景
在现代的软件开发中日期作为一个常见的基础需求广泛用于各类系统的日程管理数据分析交易记录等场景。但是C库中的时间日期功能比较有限无法满足复杂的开发需求。为此我们需要开发一款简单高效的“日期类”C项目。
项目需求
日期结构设计我们需要实现一个名为“Date”的C自定义类型包含年_year月(_month)日(_day)。并相应提供构造函数析构函数拷贝复制函数等函数。日期运算方法实现日期的加减运算支持用户通过增加或减少年、月、日来实现新的日期对象。同时提供比较两个日期大小的方法包括 、、 、 、 、!等关系操作符的重载。日期有效性检查Date类需要实现对日期有效性的严格检查确保月份正常保证闰年的判断符合各个月份的实际天数。日期格式转换提供将Date对象转换为“XXXX—YY—ZZ”的方法同时也支持从标准“XXXX—YY—ZZ”字符串中解析创建Date对象。实用工具方法提供获取当前日期判断是否为闰年计算两个日期的天数差等功能。
以上就是该项目的基本需求请务必确保程序的健壮性与可维护性。
项目实现
1 日期结构设计
该部分我们给出以下框架
class Date{public:// 获取某年某月的天数int GetMonthDay(int year, int month);//展示日期void show();// 全缺省的构造函数Date(int year 1900, int month 1, int day 1);// 拷贝构造函数// d2(d1)Date(const Date d);// 析构函数~Date();//---------------------------------------------------------------// 赋值运算符重载// d2 d3 - d2.operator(d2, d3)Date operator(const Date d);// 日期天数Date operator(int day);// 日期天数Date operator(int day);// 日期-天数Date operator-(int day);// 日期-天数Date operator-(int day);// 前置Date operator();// 后置Date operator(int);// 后置--Date operator--(int);// 前置--Date operator--();//-------------------------------------------------------------// 运算符重载bool operator(const Date d);// 运算符重载bool operator(const Date d);// 运算符重载bool operator (const Date d);// 运算符重载bool operator (const Date d);// 运算符重载bool operator (const Date d);// !运算符重载bool operator ! (const Date d);// 日期-日期 返回天数int operator-(const Date d);//-----------------------------------------------// 转换为字符串“ YYYY-MM-DD ”string toString() const;//通过字符串构建对象static Date fromString(const string dateStr);private:int _year;int _month;int _day;};这里给出较为全面的框架 成员变量私有成员变量 _year、_month 和 _day 分别表示年份、月份和日期。 构造函数 全缺省构造函数默认日期为1900年1月1日。 拷贝构造函数复制给定日期对象的所有信息。 赋值运算符重载 (operator)用于拷贝另一个Date对象的日期信息到当前对象。 算术运算符重载 和 - 运算符用于日期增加或减少指定天数。 和 - 运算符分别用于返回增加或减少指定天数后的日期对象以及两个日期之间的天数差。 自增/自减运算符重载 前缀和后缀形式的 与 – 运算符用于向前或向后移动一天。 关系运算符重载 、、、 和 分别用于比较两个日期的大小关系。 ! 判断两个日期是否不相等。 方法 show() 用于输出日期。 GetMonthDay() 根据年份和月份获取该月的天数考虑了闰年的特殊情况。 析构函数 简单地将日期成员变量设为0但在实际应用中这通常不是必要的因为类的生命周期结束后系统会自动释放其占用的内存资源。
下面我们逐一实现功能
2 构造函数
2.1 全缺省构造函数
首先我们需要提供一个全缺省的构造函数方便对象的实例化。 这里我们提供默认的1900 -1- 1作为缺省值
Date::Date(int year , int month , int day ) {_year year;_month month;_day day;
}2.2 拷贝构造函数
然后我们还需要一个拷贝构造函数让我们更加灵活的创建对象
Date::Date(const Date d) {_year d._year;_month d._month;_day d._day;
}2.3 析构函数
析构函数简单一写即可因为我们没有开辟空间不需要考虑复杂问题。
3 赋值运算符重载
这里我们需要实现 - - 前置 后置 前置-- 后置– 加和减原理类似讲解中只以加为例详细代码请看结尾全部代码。
3.1 重载
注意返回值类型这里传回引用效率更好。
Date Date::operator(const Date d) {_year d._year;_month d._month;_day d._day;//灵活使用this指针return *this;
}3.2 重载
这里我们先实现 之后再实现这样可以避免多次创建变量效率更高。 首先对于 我们需要准确知道该月的月份保证日期的有效性。
int Date::GetMonthDay(int year, int month) {int day[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)){return 29;}return day[month];
}完成重载
Date Date::operator(int day) {_day day;while (_day GetMonthDay(_year, _month)) {_day - GetMonthDay(_year, _month);_month;if (_month 12) {_year;_month 1;}}return *this;
}重载
实现了之后我们就好实现了 注意这里不能传回引用 这里是临时变量传引用会导致错误。
Date Date::operator(int day) {Date temp(*this);temp day;return temp;
}前置 和 后置
前置后置这里使用了不同参数来做区分。不得感叹祖师爷的巧妙。
//前置
Date Date::operator() {
//直接返回后答案即可return *this 1;
}
//后置 不能传引用
Date Date::operator(int) {
//创建一个临时变量来储存 前的值Date temp(*this);*this 1;//返回前的值return temp;
}4 关系操作符重载
这里十分巧妙我们只需要实现 即可通过巧妙使用完成全部操作符重载
bool Date::operator(const Date d) {return d._year _year d._month _month d._day _day;
}bool Date::operator(const Date d) {if (_year d._year) return false;else if (_month d._month) return false;else if (_day d._day) return false;else return true;}bool Date::operator (const Date d) {return *this d || *this d;
}bool Date::operator (const Date d) {return !(*this d);
}bool Date::operator (const Date d) {return !(*this d);
}bool Date::operator ! (const Date d) {return !(*this d);
}5 工具方法
5.1 计算日期差
这里使用朴素算法逐渐到较大日期即可即可
//注意正负
int Date::operator-(const Date d) {//默认前值大int flag 1;Date max *this;Date min d;if (max min) {flag -1;max d;min *this;}int day 0;while (min ! max){min;day;}return flag * day;
}5.2 日期转换为字符串
使用库函数轻松实现
string Date::toString() const {char buffer[11]; // 预留足够的空间存储 YYYY-MM-DDsnprintf(buffer, sizeof(buffer), %04d-%02d-%02d, _year, _month, _day);return string(buffer);
}5.3 通过字符串构建对象
这一步比较复杂 首先在声明中加入static 保证可以随时调用。 然后需要保证日期的合法性 最后返回类对象
static Date fromString(const string dateStr);Date Date::fromString(const std::string dateStr) {int year 0, month 0, day 0;sscanf(dateStr.c_str(), %d-%d-%d, year, month, day); // 使用sscanf解析字符串Date d(year,month,day);// 在这里应该添加必要的日期合法性检查if (month 1 || month 12) {throw std::invalid_argument(月份错误\n);}int maxDays d.GetMonthDay(year, month);if (day 1 || day maxDays) {throw std::invalid_argument(给定月份和年份的日期值无效\n);}return Date(year, month, day);
}完整源代码
Date.h
#pragma once#includeiostream
using namespace std;
class Date{public:// 获取某年某月的天数int GetMonthDay(int year, int month);//展示日期void show();// 全缺省的构造函数Date(int year 1900, int month 1, int day 1);// 拷贝构造函数// d2(d1)Date(const Date d);// 析构函数~Date();// 赋值运算符重载// d2 d3 - d2.operator(d2, d3)Date operator(const Date d);// 日期天数Date operator(int day);// 日期天数Date operator(int day);// 日期-天数Date operator-(int day);// 日期-天数Date operator-(int day);// 前置Date operator();// 后置Date operator(int);// 后置--Date operator--(int);// 前置--Date operator--();// 运算符重载bool operator(const Date d);// 运算符重载bool operator(const Date d);// 运算符重载bool operator (const Date d);// 运算符重载bool operator (const Date d);// 运算符重载bool operator (const Date d);// !运算符重载bool operator ! (const Date d);// 日期-日期 返回天数int operator-(const Date d);// 转换为字符串“ YYYY-MM-DD ”string toString() const;static Date fromString(const string dateStr);private:int _year;int _month;int _day;};Date.cpp
#includeDate.hvoid Date::show() {printf(%4d 年 %2d 月 %2d 日\n,_year,_month,_day);
}int Date::GetMonthDay(int year, int month) {int day[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)){return 29;}return day[month];
}Date::Date(int year , int month , int day ) {_year year;_month month;_day day;
}Date::Date(const Date d) {_year d._year;_month d._month;_day d._day;
}Date::~Date() {_year 0;_month 0;_day 0;
}Date Date::operator(int day) {_day day;while (_day GetMonthDay(_year, _month)) {_day - GetMonthDay(_year, _month);_month;if (_month 12) {_year;_month 1;}}return *this;
}Date Date::operator(const Date d) {_year d._year;_month d._month;_day d._day;return *this;
}Date Date::operator(int day) {Date temp(*this);temp day;return temp;
}Date Date::operator-(int day) {_day - day;while (_day 0) {_month--;if (_month 1) {_year--;_month 12;}_day GetMonthDay(_year,_month);}return *this;
}Date Date::operator-(int day) {Date temp(day);temp - day;return temp;
}Date Date::operator() {return *this 1;
}Date Date::operator(int) {Date temp(*this);*this 1;return temp;
}Date Date::operator--() {return *this - 1;
}Date Date::operator--(int) {Date temp(*this);*this - 1;return temp;
}bool Date::operator(const Date d) {return d._year _year d._month _month d._day _day;
}bool Date::operator(const Date d) {if (_year d._year) return false;else if (_month d._month) return false;else if (_day d._day) return false;else return true;}bool Date::operator (const Date d) {return *this d || *this d;
}bool Date::operator (const Date d) {return !(*this d);
}bool Date::operator (const Date d) {return !(*this d);
}bool Date::operator ! (const Date d) {return !(*this d);
}int Date::operator-(const Date d) {Date max *this;Date min d;int flag 1;if (max min) {flag -1;max d;min *this;}int day 0;while (min ! max){min;day;}return flag * day;
}string Date::toString() const {char buffer[11]; // 预留足够的空间存储 YYYY-MM-DDsnprintf(buffer, sizeof(buffer), %04d-%02d-%02d, _year, _month, _day);return string(buffer);
}Date Date::fromString(const std::string dateStr) {int year 0, month 0, day 0;sscanf(dateStr.c_str(), %d-%d-%d, year, month, day); // 使用sscanf解析字符串Date d(year,month,day);// 在这里应该添加必要的日期合法性检查if (month 1 || month 12) {throw std::invalid_argument(月份错误\n);}int maxDays d.GetMonthDay(year, month);if (day 1 || day maxDays) {throw std::invalid_argument(给定月份和年份的日期值无效\n);}return Date(year, month, day);
}Thanks♪(ω)谢谢阅读
下一篇文章见