目录
一、Date类:
二、模块化功能实现:
(1)实现日期比较
功能函数:
(2)实现日期计算:
功能函数:
(3)实现日期间隔计算
功能函数:
(4)实现输入、输出运算符重载
功能函数:
三、完整源码:
Date.h:
Date.cpp:
test.cpp:
一、Date类:
通过理解并使用构造函数、析构函数、拷贝构造函数、运算符重载、赋值重载等,实现Date类。通过Date类,实现日期计算的功能。
二、模块化功能实现:
(1)实现日期比较
功能函数:
(2)实现日期计算:
功能函数:
(3)实现日期间隔计算功能函数:
(4)实现输入、输出运算符重载
功能函数:
三、完整源码:
Date.h:
成员函数声明:
#pragma once
#include
#include
//用什么,放什么
//防止自定义的与库中的冲突
using std::cout;
using std::cin;
using std::endl;
版本1:运算符重载函数:声明与定义分离
Date类
//class Date
//{
//public:
// // 获取某年某月的天数
// int GetMonthDay(int year, int month)
// {
// static 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;
// }
// return day;
// }
//
// // 全缺省的构造函数
// Date(int year = 1900, int month = 1, int day = 1)
// {
// if (year >= 1 &&
// month <= 12 && month >= 1 &&
// day >= 1 && day <= GetMonthDay(year, month))
// {
// _year = year;
// _month = month;
// _day = day;
// }
// else
// {
// cout << "日期非法" << endl;
// }
// }
// void Print()
// {
// cout << _year << "-" <<_month << "-" << _day << endl;
// }
// // 1.拷贝构造函数
// // d2(d1)
// Date(const Date& d);
//
// // 2.赋值运算符重载
// // d2 = d3 -> d2.operator=(&d2, d3)
// Date& operator=(const Date& d);
// // 3.析构函数
// //~Date();
// // 4.日期运算
// // 日期+=天数
// 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--();
// // 日期-日期 返回天数
// int operator-(const Date& d);
//
// //5.运算符重载
// // >运算符重载
// 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);
//
// //若使用inline函数:
// //因为内联声明与定义不能分离,所以成员函数要成为内联,有两种方法
// //解决办法:
// //1.在.h文件中:在类内声明,在类外定义
// //2.在.h文件中,直接在类内定义,默认为内联函数
// //原因:
// //如果声明在.h,定义在.cpp,而测试在test.cpp
// //则在test.cpp调用时链接不到
// //例:inline bool operator >= (const Date& d);
//
//
//
//private:
// //这里只是声明,而声明不开辟空间
// //因此在类里面访问时,实参的第一个参数传给this指针,
// //第二个参数传给d(可能是传引用或者传值传参)
// //所以,还是在类里面访问成员函数,是公有的,有访问权限
// int _year;
// int _month;
// int _day;
//};
版本2:使用内联。将成员函数直接在类内定义
Date类
//class Date
//{
//public:
// // 获取某年某月的天数
// int GetMonthDay(int year, int month)
// {
// static 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;
// }
// return day;
// }
//
// // 全缺省的构造函数
// Date(int year = 1900, int month = 1, int day = 1)
// {
// if (year >= 1 &&
// month <= 12 && month >= 1 &&
// day >= 1 && day <= GetMonthDay(year, month))
// {
// _year = year;
// _month = month;
// _day = day;
// }
// else
// {
// cout << "日期非法" << endl;
// }
// }
// void Print()
// {
// cout << _year << "-" << _month << "-" << _day << endl;
// }
// // 1.拷贝构造函数
// // d2(d1)
// Date(const Date& d);
//
// // 2.赋值运算符重载
// // d2 = d3 -> d2.operator=(&d2, d3)
// Date& operator=(const Date& d);
// // 3.析构函数
// //~Date();
// // 4.日期运算
// // 日期+=天数
// 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--();
// // 日期-日期 返回天数
// int operator-(const Date& d);
//
// //2.运算符重载(附用代码+使用内联(类内定义默认))
// //1.重载运算符== 在类内定义,无需再指定类域:Date::
// bool operator == (const Date& d)
// {
// return _year == d._year
// && _month == d._month
// && _day == d._day;
// }
//
// //2.重载运算符 <
// bool operator<(const Date& d)
// {
// if ((_year < d._year)
// || (_year == d._year && _month < d._month)
// || (_year == d._year && _month == d._month && _day < d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
// }
// //3.重载运算符 >
// bool operator>(const Date& d)
// {
// //1.直接逻辑
//
// //2.附用
// return !(*this <= d);
//
// }
//
// // 4.重载运算符 >=
// bool operator >= (const Date& d)
// {
// return !(*this < d);
// }
//
// // 5.重载运算符 <=
// bool operator <= (const Date& d)
// {
// return *this < d || *this == d;
// }
// // 6.重载运算符 !=
// bool operator != (const Date& d)
// {
// return !(*this == d);
// }
// 7.重载运算符- 日期-日期 返回天数
// //int Date::operator-(const Date& d)
// //{
// //
// //}
//private:
// int _year;
// int _month;
// int _day;
//};
//版本3:运算符重载函数:声明与定义分离
//Date类
class Date
{
public:
//1.将GetMonthDay声明在类内.h,定义在类外.cpp
int GetMonthDay(int year, int month);
//2.将全缺省的构造函数声明在类内.h,定义在类外.cpp
Date(int year = 1900, int month = 1, int day = 1);
//3.将Print()声明在类内.h,定义在类外.cpp
void Print() const; //被const修饰的以及Date类型的普通变量都可以调用这个含有隐式指针this的函数
// 4.拷贝构造函数
Date(const Date& d);
// 5.赋值运算符重载
Date& operator=(const Date& d);
// 6.析构函数
//~Date();
// 7.日期运算
// 日期+=天数
Date& operator+=(int day);
// 日期+天数
Date operator+(int day);
// 日期-天数
Date operator-(int day);
// 日期-=天数
Date& operator-=(int day);
//前置和后置,函数名相同,参数相同,语法规定加一个参数予以区别
//构成函数重载
// 例:++d1,返回的是++运算后的值
// 例:d1++ 返回++之前的值
// 前置++
Date& operator++();
// 后置++
//Date operator++(int i); //int是编译器传的
//Date operator++(int i=0); //不能写成缺省参数,因为没意义,参数只是区别前置和后置
//两个函数,当函数名相同,一个无参,一个带参,调用传参时,带参的不能写成全缺省的
//就像无参的构造函数与全缺省的构造函数不能同时存在是一样的,语法上可以,但调用上不能,无法区分
//实际上形参可以不写,不写意味着不使用所传的值,传值不需要就可以省去形参
//最终版
Date operator++(int);
// 前置--
Date& operator--();
// 后置--
Date operator--(int);
// 日期-日期 返回天数
// 日期-日期和日期-天数构成函数重载
int operator-(const Date& d);
//8.运算符重载
// >运算符重载
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);
//9.取地址及const取地址操作符重载
//这两个默认成员函数一般不用重新定义 ,编译器默认会生成。
//这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,
//只有特殊情况,才需要重载,比如不想让别人获取到指定的内容!
(1)取地址操作符重载
//Date* operator&()
//{
// return this;
//}
(2)const取地址操作符重载
//const Date* operator&()const
//{
// return this;
//}
如果不想被访问地址等情况,就自己写
(1)取地址操作符重载
//Date* operator&()
//{
// return nullptr;
//}
(2)const取地址操作符重载
//const Date* operator&()const
//{
// return nullptr;
//}
//10.I/O运算符重载
// 写成全局函数,但全局函数不能在.h定义,因为会在两个.cpp展开,编译会重定义报错
// 而类内定义,默认是内联,不会放在符号表,不会重定义报错
//void operator<<(std::ostream& out)
//{
// cout << _year << "-" << _month << "-" << _day << endl;
//}
//void operator>>(std::istream& in)
//{
//}
//声明成友元函数
friend std::ostream& operator<<(std::ostream& out, const Date& d);
friend std::istream& operator>>(std::istream& in, Date& d);
private:
int _year;
int _month;
int _day;
};
10.I / O运算符重载
解决私有对象不能访问的问题
1.借用函数Getyear,这相当于放成公有了,读写均可以了
2.使用友元函数
//void operator<<(std::ostream& out,const Date& d)
//{
// cout << d._year << "-" << d._month << "-" <>(std::istream& in,const Date& d)
//{
//
//}
Date.cpp:
成员函数功能实现:
#include "Date.h"
//版本1
//运算符重载(直接逻辑):
1.重载运算符==
//bool Date::operator == (const Date& d)
//{
// return _year == d._year
// && _month == d._month
// && _day == d._day;
//}
//
2.重载运算符 <
//bool Date::operator<(const Date& d)
//{
// if ((_year < d._year)
// || (_year == d._year && _month < d._month)
// || (_year == d._year && _month == d._month && _day < d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
//}
3.重载运算符 >
//bool Date::operator>(const Date& d)
//{
// if ((_year > d._year)
// || (_year == d._year && _month > d._month)
// || (_year == d._year && _month == d._month && _day > d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
//}
//
4.重载运算符 >=
//inline bool Date::operator >= (const Date& d)
//{
//
//}
//
5.重载运算符 <=
//bool Date::operator <= (const Date& d)
//{
//
//}
6.重载运算符 !=
//bool Date::operator != (const Date& d)
//{
//
//}
7.重载运算符- 日期-日期 返回天数
//int Date::operator-(const Date& d)
//{
//
//}
//版本2
//A.运算符重载(附用代码)
//1.重载运算符== 当声明与定义分离,需要指定类域:Date::
//bool Date::operator == (const Date& d)
//{
// return _year == d._year
// && _month == d._month
// && _day == d._day;
//}
//
//2.重载运算符 <
//bool Date::operator<(const Date& d)
//{
// if ((_year < d._year)
// || (_year == d._year && _month < d._month)
// || (_year == d._year && _month == d._month && _day < d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
//}
//3.重载运算符 >
//bool Date::operator>(const Date& d)
//{
// 1.直接逻辑
//
// 2.附用
// return !(*this <= d);
//
//}
//
// 4.重载运算符 >=
//bool Date::operator >= (const Date& d)
//{
// return !(*this < d);
//}
//
// 5.重载运算符 <=
//bool Date::operator <= (const Date& d)
//{
// return *this < d || *this == d;
//}
// 6.重载运算符 !=
//bool Date::operator != (const Date& d)
//{
// return !(*this == d);
//}
7.重载运算符- 日期-日期 返回天数
//int Date::operator-(const Date& d)
//{
//
//}
//版本3
//A.运算符重载(附用代码)
//1.重载运算符== 当声明与定义分离,需要指定类域:Date::
bool Date::operator == (const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
//2.重载运算符 <
bool Date::operator<(const Date& d)
{
if ((_year < d._year)
|| (_year == d._year && _month < d._month)
|| (_year == d._year && _month == d._month && _day < d._day))
{
return true;
}
else
{
return false;
}
}
//3.重载运算符 >
bool Date::operator>(const Date& d)
{
//1.直接逻辑
//2.附用
return !(*this <= d);
}
// 4.重载运算符 >=
bool Date::operator >= (const Date& d)
{
return !(*this < d);
}
// 5.重载运算符 <=
bool Date::operator <= (const Date& d)
{
return *this < d || *this == d;
}
// 6.重载运算符 !=
bool Date::operator != (const Date& d)
{
return !(*this == d);
}
7.重载运算符- 日期-日期 返回天数
//int Date::operator-(const Date& d)
//{
//
//}
//B.
//获取某年某月的天数
int Date::GetMonthDay(int year, int month)
{
assert(year >= 0 && month > 0 && month < 13);
//GetMonthDay会频繁调用,每次都会开辟数组,加上static
//即使static有线程安全,但多个线程读影响小,写影响大
//static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
const static 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;
}
return day;
}
//构造函数
Date::Date(int year , int month , int day )
{
if (year >= 1 &&
month <= 12 && month >= 1 &&
day >= 1 && day <= GetMonthDay(year, month))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "日期非法" << endl;
}
}
//打印函数
void Date::Print() const
{
cout << _year << "-" << _month << "-" << _day << endl;
}
//拷贝构造函数
// d2(d1)
//日期类不需要写拷贝构造,这里写出来说明TestDate2中Date d3 = d1;
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
//赋值运算符重载
Date& Date::operator=(const Date& d)
{
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
//C.日期运算
// 日期+=天数
//d1+=100—>d1.operator+(day) d1自身改变
//连续d2+=d1+=100—>d1.operator+(day)
//这个需要引用返回,因为d1改变了,出作用域返回仍存在
Date& Date::operator+=(int day)
{
//1.直接实现
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;
2.附用+
/
//cout重载
//operator<<(cout, d1);
//cout << d1<> d3;
cin >> d3 >> d4;
cout << d3 << d4; //结合:从左到右
}
int main()
{
//TestDate1();
//TestDate2();
//TestDate3();
//TestDate4();
//TestDate5();
//TestDate6();
//TestDate7();
//TestDate8();
TestDate9();
return 0;
}
cout、cin重载:
cin和cout能自动识别类型,是因为库实现了函数重载,将常见的类型写为函数重载
后记:
●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!
——By 作者:新晓·故知
通过理解并使用构造函数、析构函数、拷贝构造函数、运算符重载、赋值重载等,实现Date类。通过Date类,实现日期计算的功能。
(1)实现日期比较
功能函数:
(2)实现日期计算:
功能函数:
(3)实现日期间隔计算功能函数:
(4)实现输入、输出运算符重载
功能函数:
三、完整源码:
Date.h:
成员函数声明:
#pragma once
#include
#include
//用什么,放什么
//防止自定义的与库中的冲突
using std::cout;
using std::cin;
using std::endl;
版本1:运算符重载函数:声明与定义分离
Date类
//class Date
//{
//public:
// // 获取某年某月的天数
// int GetMonthDay(int year, int month)
// {
// static 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;
// }
// return day;
// }
//
// // 全缺省的构造函数
// Date(int year = 1900, int month = 1, int day = 1)
// {
// if (year >= 1 &&
// month <= 12 && month >= 1 &&
// day >= 1 && day <= GetMonthDay(year, month))
// {
// _year = year;
// _month = month;
// _day = day;
// }
// else
// {
// cout << "日期非法" << endl;
// }
// }
// void Print()
// {
// cout << _year << "-" <<_month << "-" << _day << endl;
// }
// // 1.拷贝构造函数
// // d2(d1)
// Date(const Date& d);
//
// // 2.赋值运算符重载
// // d2 = d3 -> d2.operator=(&d2, d3)
// Date& operator=(const Date& d);
// // 3.析构函数
// //~Date();
// // 4.日期运算
// // 日期+=天数
// 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--();
// // 日期-日期 返回天数
// int operator-(const Date& d);
//
// //5.运算符重载
// // >运算符重载
// 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);
//
// //若使用inline函数:
// //因为内联声明与定义不能分离,所以成员函数要成为内联,有两种方法
// //解决办法:
// //1.在.h文件中:在类内声明,在类外定义
// //2.在.h文件中,直接在类内定义,默认为内联函数
// //原因:
// //如果声明在.h,定义在.cpp,而测试在test.cpp
// //则在test.cpp调用时链接不到
// //例:inline bool operator >= (const Date& d);
//
//
//
//private:
// //这里只是声明,而声明不开辟空间
// //因此在类里面访问时,实参的第一个参数传给this指针,
// //第二个参数传给d(可能是传引用或者传值传参)
// //所以,还是在类里面访问成员函数,是公有的,有访问权限
// int _year;
// int _month;
// int _day;
//};
版本2:使用内联。将成员函数直接在类内定义
Date类
//class Date
//{
//public:
// // 获取某年某月的天数
// int GetMonthDay(int year, int month)
// {
// static 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;
// }
// return day;
// }
//
// // 全缺省的构造函数
// Date(int year = 1900, int month = 1, int day = 1)
// {
// if (year >= 1 &&
// month <= 12 && month >= 1 &&
// day >= 1 && day <= GetMonthDay(year, month))
// {
// _year = year;
// _month = month;
// _day = day;
// }
// else
// {
// cout << "日期非法" << endl;
// }
// }
// void Print()
// {
// cout << _year << "-" << _month << "-" << _day << endl;
// }
// // 1.拷贝构造函数
// // d2(d1)
// Date(const Date& d);
//
// // 2.赋值运算符重载
// // d2 = d3 -> d2.operator=(&d2, d3)
// Date& operator=(const Date& d);
// // 3.析构函数
// //~Date();
// // 4.日期运算
// // 日期+=天数
// 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--();
// // 日期-日期 返回天数
// int operator-(const Date& d);
//
// //2.运算符重载(附用代码+使用内联(类内定义默认))
// //1.重载运算符== 在类内定义,无需再指定类域:Date::
// bool operator == (const Date& d)
// {
// return _year == d._year
// && _month == d._month
// && _day == d._day;
// }
//
// //2.重载运算符 <
// bool operator<(const Date& d)
// {
// if ((_year < d._year)
// || (_year == d._year && _month < d._month)
// || (_year == d._year && _month == d._month && _day < d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
// }
// //3.重载运算符 >
// bool operator>(const Date& d)
// {
// //1.直接逻辑
//
// //2.附用
// return !(*this <= d);
//
// }
//
// // 4.重载运算符 >=
// bool operator >= (const Date& d)
// {
// return !(*this < d);
// }
//
// // 5.重载运算符 <=
// bool operator <= (const Date& d)
// {
// return *this < d || *this == d;
// }
// // 6.重载运算符 !=
// bool operator != (const Date& d)
// {
// return !(*this == d);
// }
// 7.重载运算符- 日期-日期 返回天数
// //int Date::operator-(const Date& d)
// //{
// //
// //}
//private:
// int _year;
// int _month;
// int _day;
//};
//版本3:运算符重载函数:声明与定义分离
//Date类
class Date
{
public:
//1.将GetMonthDay声明在类内.h,定义在类外.cpp
int GetMonthDay(int year, int month);
//2.将全缺省的构造函数声明在类内.h,定义在类外.cpp
Date(int year = 1900, int month = 1, int day = 1);
//3.将Print()声明在类内.h,定义在类外.cpp
void Print() const; //被const修饰的以及Date类型的普通变量都可以调用这个含有隐式指针this的函数
// 4.拷贝构造函数
Date(const Date& d);
// 5.赋值运算符重载
Date& operator=(const Date& d);
// 6.析构函数
//~Date();
// 7.日期运算
// 日期+=天数
Date& operator+=(int day);
// 日期+天数
Date operator+(int day);
// 日期-天数
Date operator-(int day);
// 日期-=天数
Date& operator-=(int day);
//前置和后置,函数名相同,参数相同,语法规定加一个参数予以区别
//构成函数重载
// 例:++d1,返回的是++运算后的值
// 例:d1++ 返回++之前的值
// 前置++
Date& operator++();
// 后置++
//Date operator++(int i); //int是编译器传的
//Date operator++(int i=0); //不能写成缺省参数,因为没意义,参数只是区别前置和后置
//两个函数,当函数名相同,一个无参,一个带参,调用传参时,带参的不能写成全缺省的
//就像无参的构造函数与全缺省的构造函数不能同时存在是一样的,语法上可以,但调用上不能,无法区分
//实际上形参可以不写,不写意味着不使用所传的值,传值不需要就可以省去形参
//最终版
Date operator++(int);
// 前置--
Date& operator--();
// 后置--
Date operator--(int);
// 日期-日期 返回天数
// 日期-日期和日期-天数构成函数重载
int operator-(const Date& d);
//8.运算符重载
// >运算符重载
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);
//9.取地址及const取地址操作符重载
//这两个默认成员函数一般不用重新定义 ,编译器默认会生成。
//这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,
//只有特殊情况,才需要重载,比如不想让别人获取到指定的内容!
(1)取地址操作符重载
//Date* operator&()
//{
// return this;
//}
(2)const取地址操作符重载
//const Date* operator&()const
//{
// return this;
//}
如果不想被访问地址等情况,就自己写
(1)取地址操作符重载
//Date* operator&()
//{
// return nullptr;
//}
(2)const取地址操作符重载
//const Date* operator&()const
//{
// return nullptr;
//}
//10.I/O运算符重载
// 写成全局函数,但全局函数不能在.h定义,因为会在两个.cpp展开,编译会重定义报错
// 而类内定义,默认是内联,不会放在符号表,不会重定义报错
//void operator<<(std::ostream& out)
//{
// cout << _year << "-" << _month << "-" << _day << endl;
//}
//void operator>>(std::istream& in)
//{
//}
//声明成友元函数
friend std::ostream& operator<<(std::ostream& out, const Date& d);
friend std::istream& operator>>(std::istream& in, Date& d);
private:
int _year;
int _month;
int _day;
};
10.I / O运算符重载
解决私有对象不能访问的问题
1.借用函数Getyear,这相当于放成公有了,读写均可以了
2.使用友元函数
//void operator<<(std::ostream& out,const Date& d)
//{
// cout << d._year << "-" << d._month << "-" <>(std::istream& in,const Date& d)
//{
//
//}
Date.cpp:
成员函数功能实现:
#include "Date.h"
//版本1
//运算符重载(直接逻辑):
1.重载运算符==
//bool Date::operator == (const Date& d)
//{
// return _year == d._year
// && _month == d._month
// && _day == d._day;
//}
//
2.重载运算符 <
//bool Date::operator<(const Date& d)
//{
// if ((_year < d._year)
// || (_year == d._year && _month < d._month)
// || (_year == d._year && _month == d._month && _day < d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
//}
3.重载运算符 >
//bool Date::operator>(const Date& d)
//{
// if ((_year > d._year)
// || (_year == d._year && _month > d._month)
// || (_year == d._year && _month == d._month && _day > d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
//}
//
4.重载运算符 >=
//inline bool Date::operator >= (const Date& d)
//{
//
//}
//
5.重载运算符 <=
//bool Date::operator <= (const Date& d)
//{
//
//}
6.重载运算符 !=
//bool Date::operator != (const Date& d)
//{
//
//}
7.重载运算符- 日期-日期 返回天数
//int Date::operator-(const Date& d)
//{
//
//}
//版本2
//A.运算符重载(附用代码)
//1.重载运算符== 当声明与定义分离,需要指定类域:Date::
//bool Date::operator == (const Date& d)
//{
// return _year == d._year
// && _month == d._month
// && _day == d._day;
//}
//
//2.重载运算符 <
//bool Date::operator<(const Date& d)
//{
// if ((_year < d._year)
// || (_year == d._year && _month < d._month)
// || (_year == d._year && _month == d._month && _day < d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
//}
//3.重载运算符 >
//bool Date::operator>(const Date& d)
//{
// 1.直接逻辑
//
// 2.附用
// return !(*this <= d);
//
//}
//
// 4.重载运算符 >=
//bool Date::operator >= (const Date& d)
//{
// return !(*this < d);
//}
//
// 5.重载运算符 <=
//bool Date::operator <= (const Date& d)
//{
// return *this < d || *this == d;
//}
// 6.重载运算符 !=
//bool Date::operator != (const Date& d)
//{
// return !(*this == d);
//}
7.重载运算符- 日期-日期 返回天数
//int Date::operator-(const Date& d)
//{
//
//}
//版本3
//A.运算符重载(附用代码)
//1.重载运算符== 当声明与定义分离,需要指定类域:Date::
bool Date::operator == (const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
//2.重载运算符 <
bool Date::operator<(const Date& d)
{
if ((_year < d._year)
|| (_year == d._year && _month < d._month)
|| (_year == d._year && _month == d._month && _day < d._day))
{
return true;
}
else
{
return false;
}
}
//3.重载运算符 >
bool Date::operator>(const Date& d)
{
//1.直接逻辑
//2.附用
return !(*this <= d);
}
// 4.重载运算符 >=
bool Date::operator >= (const Date& d)
{
return !(*this < d);
}
// 5.重载运算符 <=
bool Date::operator <= (const Date& d)
{
return *this < d || *this == d;
}
// 6.重载运算符 !=
bool Date::operator != (const Date& d)
{
return !(*this == d);
}
7.重载运算符- 日期-日期 返回天数
//int Date::operator-(const Date& d)
//{
//
//}
//B.
//获取某年某月的天数
int Date::GetMonthDay(int year, int month)
{
assert(year >= 0 && month > 0 && month < 13);
//GetMonthDay会频繁调用,每次都会开辟数组,加上static
//即使static有线程安全,但多个线程读影响小,写影响大
//static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
const static 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;
}
return day;
}
//构造函数
Date::Date(int year , int month , int day )
{
if (year >= 1 &&
month <= 12 && month >= 1 &&
day >= 1 && day <= GetMonthDay(year, month))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "日期非法" << endl;
}
}
//打印函数
void Date::Print() const
{
cout << _year << "-" << _month << "-" << _day << endl;
}
//拷贝构造函数
// d2(d1)
//日期类不需要写拷贝构造,这里写出来说明TestDate2中Date d3 = d1;
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
//赋值运算符重载
Date& Date::operator=(const Date& d)
{
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
//C.日期运算
// 日期+=天数
//d1+=100—>d1.operator+(day) d1自身改变
//连续d2+=d1+=100—>d1.operator+(day)
//这个需要引用返回,因为d1改变了,出作用域返回仍存在
Date& Date::operator+=(int day)
{
//1.直接实现
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;
2.附用+
/
//cout重载
//operator<<(cout, d1);
//cout << d1<> d3;
cin >> d3 >> d4;
cout << d3 << d4; //结合:从左到右
}
int main()
{
//TestDate1();
//TestDate2();
//TestDate3();
//TestDate4();
//TestDate5();
//TestDate6();
//TestDate7();
//TestDate8();
TestDate9();
return 0;
}
cout、cin重载:
cin和cout能自动识别类型,是因为库实现了函数重载,将常见的类型写为函数重载
后记:
●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!
——By 作者:新晓·故知
Date.h:
成员函数声明:
#pragma once #include#include //用什么,放什么 //防止自定义的与库中的冲突 using std::cout; using std::cin; using std::endl; 版本1:运算符重载函数:声明与定义分离 Date类 //class Date //{ //public: // // 获取某年某月的天数 // int GetMonthDay(int year, int month) // { // static 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; // } // return day; // } // // // 全缺省的构造函数 // Date(int year = 1900, int month = 1, int day = 1) // { // if (year >= 1 && // month <= 12 && month >= 1 && // day >= 1 && day <= GetMonthDay(year, month)) // { // _year = year; // _month = month; // _day = day; // } // else // { // cout << "日期非法" << endl; // } // } // void Print() // { // cout << _year << "-" <<_month << "-" << _day << endl; // } // // 1.拷贝构造函数 // // d2(d1) // Date(const Date& d); // // // 2.赋值运算符重载 // // d2 = d3 -> d2.operator=(&d2, d3) // Date& operator=(const Date& d); // // 3.析构函数 // //~Date(); // // 4.日期运算 // // 日期+=天数 // 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--(); // // 日期-日期 返回天数 // int operator-(const Date& d); // // //5.运算符重载 // // >运算符重载 // 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); // // //若使用inline函数: // //因为内联声明与定义不能分离,所以成员函数要成为内联,有两种方法 // //解决办法: // //1.在.h文件中:在类内声明,在类外定义 // //2.在.h文件中,直接在类内定义,默认为内联函数 // //原因: // //如果声明在.h,定义在.cpp,而测试在test.cpp // //则在test.cpp调用时链接不到 // //例:inline bool operator >= (const Date& d); // // // //private: // //这里只是声明,而声明不开辟空间 // //因此在类里面访问时,实参的第一个参数传给this指针, // //第二个参数传给d(可能是传引用或者传值传参) // //所以,还是在类里面访问成员函数,是公有的,有访问权限 // int _year; // int _month; // int _day; //}; 版本2:使用内联。将成员函数直接在类内定义 Date类 //class Date //{ //public: // // 获取某年某月的天数 // int GetMonthDay(int year, int month) // { // static 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; // } // return day; // } // // // 全缺省的构造函数 // Date(int year = 1900, int month = 1, int day = 1) // { // if (year >= 1 && // month <= 12 && month >= 1 && // day >= 1 && day <= GetMonthDay(year, month)) // { // _year = year; // _month = month; // _day = day; // } // else // { // cout << "日期非法" << endl; // } // } // void Print() // { // cout << _year << "-" << _month << "-" << _day << endl; // } // // 1.拷贝构造函数 // // d2(d1) // Date(const Date& d); // // // 2.赋值运算符重载 // // d2 = d3 -> d2.operator=(&d2, d3) // Date& operator=(const Date& d); // // 3.析构函数 // //~Date(); // // 4.日期运算 // // 日期+=天数 // 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--(); // // 日期-日期 返回天数 // int operator-(const Date& d); // // //2.运算符重载(附用代码+使用内联(类内定义默认)) // //1.重载运算符== 在类内定义,无需再指定类域:Date:: // bool operator == (const Date& d) // { // return _year == d._year // && _month == d._month // && _day == d._day; // } // // //2.重载运算符 < // bool operator<(const Date& d) // { // if ((_year < d._year) // || (_year == d._year && _month < d._month) // || (_year == d._year && _month == d._month && _day < d._day)) // { // return true; // } // else // { // return false; // } // } // //3.重载运算符 > // bool operator>(const Date& d) // { // //1.直接逻辑 // // //2.附用 // return !(*this <= d); // // } // // // 4.重载运算符 >= // bool operator >= (const Date& d) // { // return !(*this < d); // } // // // 5.重载运算符 <= // bool operator <= (const Date& d) // { // return *this < d || *this == d; // } // // 6.重载运算符 != // bool operator != (const Date& d) // { // return !(*this == d); // } // 7.重载运算符- 日期-日期 返回天数 // //int Date::operator-(const Date& d) // //{ // // // //} //private: // int _year; // int _month; // int _day; //}; //版本3:运算符重载函数:声明与定义分离 //Date类 class Date { public: //1.将GetMonthDay声明在类内.h,定义在类外.cpp int GetMonthDay(int year, int month); //2.将全缺省的构造函数声明在类内.h,定义在类外.cpp Date(int year = 1900, int month = 1, int day = 1); //3.将Print()声明在类内.h,定义在类外.cpp void Print() const; //被const修饰的以及Date类型的普通变量都可以调用这个含有隐式指针this的函数 // 4.拷贝构造函数 Date(const Date& d); // 5.赋值运算符重载 Date& operator=(const Date& d); // 6.析构函数 //~Date(); // 7.日期运算 // 日期+=天数 Date& operator+=(int day); // 日期+天数 Date operator+(int day); // 日期-天数 Date operator-(int day); // 日期-=天数 Date& operator-=(int day); //前置和后置,函数名相同,参数相同,语法规定加一个参数予以区别 //构成函数重载 // 例:++d1,返回的是++运算后的值 // 例:d1++ 返回++之前的值 // 前置++ Date& operator++(); // 后置++ //Date operator++(int i); //int是编译器传的 //Date operator++(int i=0); //不能写成缺省参数,因为没意义,参数只是区别前置和后置 //两个函数,当函数名相同,一个无参,一个带参,调用传参时,带参的不能写成全缺省的 //就像无参的构造函数与全缺省的构造函数不能同时存在是一样的,语法上可以,但调用上不能,无法区分 //实际上形参可以不写,不写意味着不使用所传的值,传值不需要就可以省去形参 //最终版 Date operator++(int); // 前置-- Date& operator--(); // 后置-- Date operator--(int); // 日期-日期 返回天数 // 日期-日期和日期-天数构成函数重载 int operator-(const Date& d); //8.运算符重载 // >运算符重载 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); //9.取地址及const取地址操作符重载 //这两个默认成员函数一般不用重新定义 ,编译器默认会生成。 //这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可, //只有特殊情况,才需要重载,比如不想让别人获取到指定的内容! (1)取地址操作符重载 //Date* operator&() //{ // return this; //} (2)const取地址操作符重载 //const Date* operator&()const //{ // return this; //} 如果不想被访问地址等情况,就自己写 (1)取地址操作符重载 //Date* operator&() //{ // return nullptr; //} (2)const取地址操作符重载 //const Date* operator&()const //{ // return nullptr; //} //10.I/O运算符重载 // 写成全局函数,但全局函数不能在.h定义,因为会在两个.cpp展开,编译会重定义报错 // 而类内定义,默认是内联,不会放在符号表,不会重定义报错 //void operator<<(std::ostream& out) //{ // cout << _year << "-" << _month << "-" << _day << endl; //} //void operator>>(std::istream& in) //{ //} //声明成友元函数 friend std::ostream& operator<<(std::ostream& out, const Date& d); friend std::istream& operator>>(std::istream& in, Date& d); private: int _year; int _month; int _day; }; 10.I / O运算符重载 解决私有对象不能访问的问题 1.借用函数Getyear,这相当于放成公有了,读写均可以了 2.使用友元函数 //void operator<<(std::ostream& out,const Date& d) //{ // cout << d._year << "-" << d._month << "-" < >(std::istream& in,const Date& d) //{ // //}
Date.cpp:
成员函数功能实现:
#include "Date.h"
//版本1
//运算符重载(直接逻辑):
1.重载运算符==
//bool Date::operator == (const Date& d)
//{
// return _year == d._year
// && _month == d._month
// && _day == d._day;
//}
//
2.重载运算符 <
//bool Date::operator<(const Date& d)
//{
// if ((_year < d._year)
// || (_year == d._year && _month < d._month)
// || (_year == d._year && _month == d._month && _day < d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
//}
3.重载运算符 >
//bool Date::operator>(const Date& d)
//{
// if ((_year > d._year)
// || (_year == d._year && _month > d._month)
// || (_year == d._year && _month == d._month && _day > d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
//}
//
4.重载运算符 >=
//inline bool Date::operator >= (const Date& d)
//{
//
//}
//
5.重载运算符 <=
//bool Date::operator <= (const Date& d)
//{
//
//}
6.重载运算符 !=
//bool Date::operator != (const Date& d)
//{
//
//}
7.重载运算符- 日期-日期 返回天数
//int Date::operator-(const Date& d)
//{
//
//}
//版本2
//A.运算符重载(附用代码)
//1.重载运算符== 当声明与定义分离,需要指定类域:Date::
//bool Date::operator == (const Date& d)
//{
// return _year == d._year
// && _month == d._month
// && _day == d._day;
//}
//
//2.重载运算符 <
//bool Date::operator<(const Date& d)
//{
// if ((_year < d._year)
// || (_year == d._year && _month < d._month)
// || (_year == d._year && _month == d._month && _day < d._day))
// {
// return true;
// }
// else
// {
// return false;
// }
//}
//3.重载运算符 >
//bool Date::operator>(const Date& d)
//{
// 1.直接逻辑
//
// 2.附用
// return !(*this <= d);
//
//}
//
// 4.重载运算符 >=
//bool Date::operator >= (const Date& d)
//{
// return !(*this < d);
//}
//
// 5.重载运算符 <=
//bool Date::operator <= (const Date& d)
//{
// return *this < d || *this == d;
//}
// 6.重载运算符 !=
//bool Date::operator != (const Date& d)
//{
// return !(*this == d);
//}
7.重载运算符- 日期-日期 返回天数
//int Date::operator-(const Date& d)
//{
//
//}
//版本3
//A.运算符重载(附用代码)
//1.重载运算符== 当声明与定义分离,需要指定类域:Date::
bool Date::operator == (const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
//2.重载运算符 <
bool Date::operator<(const Date& d)
{
if ((_year < d._year)
|| (_year == d._year && _month < d._month)
|| (_year == d._year && _month == d._month && _day < d._day))
{
return true;
}
else
{
return false;
}
}
//3.重载运算符 >
bool Date::operator>(const Date& d)
{
//1.直接逻辑
//2.附用
return !(*this <= d);
}
// 4.重载运算符 >=
bool Date::operator >= (const Date& d)
{
return !(*this < d);
}
// 5.重载运算符 <=
bool Date::operator <= (const Date& d)
{
return *this < d || *this == d;
}
// 6.重载运算符 !=
bool Date::operator != (const Date& d)
{
return !(*this == d);
}
7.重载运算符- 日期-日期 返回天数
//int Date::operator-(const Date& d)
//{
//
//}
//B.
//获取某年某月的天数
int Date::GetMonthDay(int year, int month)
{
assert(year >= 0 && month > 0 && month < 13);
//GetMonthDay会频繁调用,每次都会开辟数组,加上static
//即使static有线程安全,但多个线程读影响小,写影响大
//static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
const static 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;
}
return day;
}
//构造函数
Date::Date(int year , int month , int day )
{
if (year >= 1 &&
month <= 12 && month >= 1 &&
day >= 1 && day <= GetMonthDay(year, month))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "日期非法" << endl;
}
}
//打印函数
void Date::Print() const
{
cout << _year << "-" << _month << "-" << _day << endl;
}
//拷贝构造函数
// d2(d1)
//日期类不需要写拷贝构造,这里写出来说明TestDate2中Date d3 = d1;
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
//赋值运算符重载
Date& Date::operator=(const Date& d)
{
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
//C.日期运算
// 日期+=天数
//d1+=100—>d1.operator+(day) d1自身改变
//连续d2+=d1+=100—>d1.operator+(day)
//这个需要引用返回,因为d1改变了,出作用域返回仍存在
Date& Date::operator+=(int day)
{
//1.直接实现
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;
2.附用+
/
//cout重载
//operator<<(cout, d1);
//cout << d1<> d3;
cin >> d3 >> d4;
cout << d3 << d4; //结合:从左到右
}
int main()
{
//TestDate1();
//TestDate2();
//TestDate3();
//TestDate4();
//TestDate5();
//TestDate6();
//TestDate7();
//TestDate8();
TestDate9();
return 0;
}
cout、cin重载:
cin和cout能自动识别类型,是因为库实现了函数重载,将常见的类型写为函数重载
●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!



