当我们写下:
class Date{ }
哪怕我们什么都不写其实相当于我们已经写下:
——————————————-
class Date{
public:
Date();
~Date();
Date(const Date&
);
Date&
operator=(const Date&
);
}
———————————————-
所以,当我们写出一个类名的时候,那么什么都不做,其实编译器已经为我们准备了4个默认函数。
好了,现在重新回到我们的正题来,其实关于Date这个界面我们已经开发得差不多了,所以我们今天来尝试着使用这个库:
———————————-
#include <iostream>#include “Data.h”
int main()
{
My_Code::Date today;
My_Code::Date tomorrow = today;
tomorow.Add_day(1);
std::cout<<today.day()<<std::endl;
std::cout<<tomorrow.day()<<std::endl;
return 0;
}
————————————–
我们运行程序可以得到如下结果:
—————-
28
1
—————–

这就是我们用了两晚上的时间写出来的Date库,但是我们把这个Date类放在名称空间My_Code,所以我们想要使用Date,就必须得这样使:
My_Code::Date
凡是想要使用名称空间中的任何东西,都必须得这样使。
到此处,我们还是发现这个Date库不够完整,就比如说,他还缺少一个能够显示信息的函数,所以我们在class的定义里添加了下面的函数原型:
——————————-
void Show()
———————————-
然后我们可以这样来实现:
————————————–
void Date::Show()
{
cout<<m<<“/”<<d<<“/”
<<y<<endl;
}
————————————–
于是我们可以重新修改上面的主函数:
————————————–
#include “Data.h”
int main()
{
My_Code::Date today;
My_Code::Date tomorrow = today;
tomorow.Add_day(1);
today.Show();
tomorrow.Show()
return 0;
}
————————————–
运行程序,将得到下面的结果:
————–
2/28/2014
3/1/2014
—————

现在看来似乎有些完美了,我们从头从未都只使用Date来完成各种操作,我们还可以这样写:
———————————————–
tomorow.Add_day(1).Add_month(2);
————————————————
这将表示两个月后的明天,同样可以实现几年后等等,仔细想了下,对于这个Date库,我们还要实现些什么功能呢?
判断两个对象是不是同一天,还有计算出两个对象之间的差或者是和,不过计算差还有点意义,但是计算和的话就没啥啥意义,就好比,2/28/2014 + 3/8/2014一样,大家有意义吗?但是反过来就不一样了,我们可以用3/8/2014 – 2/28/2014可以得到一个两个对象的差距。
到这里,问大家一个问题,我们可以直接使用tomorrow – today这样的表达式吗?
当然不能,我们平时使用的各种运算符,那是因为编译器在内部已经重载了这些操作符,所以我们如果想要在我们自定义的类使用运算符,我们就必须得重载这些操作符。
——————————————-
Date&
operator-(const Date&
rd)
——————————————–
这个函数实现起来有些复杂,我在想是留给大家作业呢还是留给大家作业呢?大家可以参考下面我自己实现的这个,然后思考问题出在那里:
———————————————
Date&
Date::operator-(const Date&
rd)
{
if(d <rd.d)
{
m–;
d += 30-rd.d;
}
else
d -= rd.d;
if(m<rd.m)
{
y–;
m = m+12-rd.m;
}
else
m -= rd.m;
if(y<rd.y)
{
cout<<“表达式有误”<<endl;
}
else
y -= rd.y;
return *this;
}
————————————-
不管怎么样,既然我们写出这个实现,那么我们就要测试一下,看看问题出现在那里:
————————————-
Date Diff = tomorrow – today;
Diff.Show();
————————————–
然后我们会看到如同下面的输出:
———————–
2/3/0
———————-
为什么会是这样呢?其实,只是相差两月零1天而已,为什么会是2个月零3天呢?大家一定想起来了,是因为不同的月份有不同的天数,而我们的today正是今天2/28/2014,而二月份正好只有28天,而我们使用30天,所以问题就出在这里,那么该怎么解决呢?这就留给大家去思考了。
现在,我们该来总结一下怎么写出一个高效的类:
———————————–
//Date.h
#pragma once
namespace My_Code{
int leap_year(int n);
lass Date
{
int m,d,y;
static Date default_day;
public:
enum Month{jan=1,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec };
Date(int,Month,int);
Date(int,Month);
Date(int);
Date();
ate&
Add_year(int n);
Date&
Add_month(int n);
Date&
Add_day(int n);
inline
int day() const
{
return d;
}
inline Month month() const
{
return Month(m);
}
inline
int year() const
{
return y;
}
Date(const Date&
);
Date&
operator=(const Date&
);
Date&
operator-(const Date&
);
void Show();
static
void set_default(int,Month,int);
};
}
——————————————
我的实现是不完整的,大家试着尝试一下找出不完美之处,然后自行修改一下,有问题可以提出(因为字数限制的原因,所以无法把所有代码全部贴出来,我想了下,要不明天把代码发出来吧,然后大家再看看那些地方是不恰当的,然后自己修改验证一下,C++代码是可以重复使用的,大家可以把一些觉得使用的收藏起来,以后开发大型程序的时候或许会派上用场哦,就像我们现在写的这个类,如果以后我想要开发一个个日历或者什么大型软件时,可能会需要在里面插入一个和Date相关的东西,那时候我们可以把今天的Date当成基类去派生我们想要的类就好)。
———————————————-
//Date.cpp
#include “Data.h”
#include <iostream>using namespace std;
namespace My_Code
{
int leap_year(int n)
{
if(n%4 == 0 &
&
n%100 != 0)
return 1;
return 0;
}
Date Date::default_day(28,feb,2014);
void Date::set_default(int d,Month m,int y)
{
Date::default_day = Date(d,m,y);
}
Date::Date(int dd,Month mm,int yy)
{
if(dd==0)
dd = default_day.day();
if(mm==0)
mm = default_day.month();
if(yy==0)
yy = default_day.year();
int maxday;
switch (mm)
{
case jan:
case may:
case mar:
case jul:
case aug:
case oct:
case dec:
maxday = 31;
break;
case feb:
maxday = 28 + leap_year(yy);
break;
case apr:
case jun:
case sep:
case nov:
maxday = 30;
break;
default:
cout<<“初始化失败”<<endl;
break;
}
if(dd<1 || dd>maxday)
cout<<“初始化失败”<<endl;
d = dd;
m = mm;
y = yy;
}
ate&
Date::Add_year(int n)
{
if(d==29 &
&
m==2 &
&
leap_year(y+n) != 0)
{
d = 1;
m = 3;
}
y += n;
return *this;
}
Date&
Date::Add_month(int n)
{
if(n==0)
return *this;
if(n>=0)
{
int temp_y = n/12;
int temp_m = m + n%12;
if(temp_m>12)
{
temp_y++;
m = temp_m-12;
}
y += temp_y;
m = Month(temp_m);
}
if(n<0)
{
cout<<“参数有误”<<endl;
//关于这里大家可以自行实现,当然如果真不想要负数的话,可以在这里设置抛出异常。
}
return *this;
}
…………
Date::Date(const Date&
t)
{
d = t.d;
m = t.m;
y = t.y;
}
Date&
Date::operator=(const Date&
t)
{
if(this == &
t)
return *this;
d = t.d;
m = t.m;
y = t.y;
return *this;
}
…………
void Date::Show()
{
cout<<(Month)m<<“/”<<d<<“/”<<y<<endl;
}
}