例三演示了Date类。主要重载了前置++和后置++。将在程序之后描述如何重载前置++和后置++
//Date.h
#ifndef DATE_H
#define DATE_H
#include<iostream.h>
class Date
{
friend ostream &operator<<( ostream &, const Date&);
public:
Date(int m=1, int d=1, int y=1900);
void setDate(int, int, int);
Date &operator++(void);//prefix increment. Like ++Date. And void is the sign for this function.
Date operator++(int);//postfix increment. Like Date++. And int is the sign for this function.
Date &operator+=(int);
bool leapYear(int) const;
bool endOfMonth(int) const;
void helpIncrement();
void setDays();
private:
int month;
int day;
int year;
int days[13];
};
#endif
//Date.cpp
#include "Date.h"
Date::Date(int m, int d, int y)
{
setDays();
setDate(m, d, y);
}
void Date::setDate(int m, int d, int y)
{
month = (m>=1&&m<=12)?m:1;
year = (y>=1&&y<=2200)?y:1900;
if (month==2&&leapYear(year))
day = (d>=1&&d<=29)?d:1;
else
day = (d>=1&&d<=days[month])?d:1;
}
Date &Date::operator ++(void)//!!!!!!!!!!!!!!!!!!!!!
{
helpIncrement();
return *this;
}
Date Date::operator ++(int)//!!!!!!!!!!!!!!!!!!!!!
{
Date temp = *this;
helpIncrement();
return temp;
}
Date &Date::operator +=(int n)
{
for (int i=0;i<n;i++)
helpIncrement();
return *this;
}
bool Date::leapYear(int y) const
{
if (y%400==0||(y%100!=0&&y%4==0))
return true;
else
return false;
}
//perfect!!!!!!!
bool Date::endOfMonth(int d) const
{
if (month==2&&leapYear(year))
return d==29;
else
return d==days[month];
}
void Date::helpIncrement()
{
if (!endOfMonth(day))
day++;
else
{
if (month<12)
{
month++;
}
else
{
year++;
month=1;
}
day=1;
}
}
void Date::setDays()
{
days[0]=0;
days[1]=31;
days[2]=28;
days[3]=31;
days[4]=30;
days[5]=31;
days[6]=30;
days[7]=31;
days[8]=31;
days[9]=30;
days[10]=31;
days[11]=30;
days[12]=31;
}
ostream &operator<<(ostream &output, const Date &date)
{
output<<date.month<<" "<<date.day<<" "<<date.year<<endl;
return output;
}
//run.cpp
#include<iostream.h>
#include "Date.h"
void main()
{
Date d1;
Date d2(12,27,1992);
Date d3(0,99,2132);
cout<<"d1 is "<<d1<<endl;
cout<<"d2 is "<<d2<<endl;
cout<<"d3 is "<<d3<<endl;
cout<<"/n/nd2 += 7 is "<<(d2+=7);
d3.setDate(2,28,1992);
cout<<"/n/nd3 is "<<d3;
cout<<"/n++d3 is "<<++d3;
Date d4(7,13,2002);
cout<<"d4 is "<<d4<<endl;
cout<<"++d4 is "<<++d4<<endl;
cout<<"d4 is "<<d4<<endl;
cout<<"d4++ is "<<d4++<<endl;
cout<<"d4 is "<<d4<<endl;
}
重载的前置自增运算符返回当前的Date对象的引用,也就是刚刚自增后的对象(例如:cout<<++n,输出n+1。而cout<<n++,输出n)。因为当前对象*this是作为Date&返回的,这使前置自增的Date对象可以作为左值来使用,正如内置的前置自增运算符对基本类型的工作方式。
重载的后置自增运算符更复杂一些。为了仿制内置的后置自增运算的效果,我们必须返回Date对象自增之前的一份副本。所以在函数中,把*this保存到temp中。然后再调用helpIncrement递增当前的Date对象。最后返回temp中的对象自增前的副本。
注意:该函数不能返回局部Date对象temp的引用,因为局部变量在其声明所在的函数退出时便销毁了。
Date &operator++(void)与Date operator++(int),为了使编译器区别两个函数,一个传入参数为(void),另一个是(int)。
实际上重载前置自增运算符与后置自增运算符完全遵循内置的运算规律。换句话说,重载前置自增运算符与后置自增运算符只要理解性的记下来就好。
//Date.h
#ifndef DATE_H
#define DATE_H
#include<iostream.h>
class Date
{
friend ostream &operator<<( ostream &, const Date&);
public:
Date(int m=1, int d=1, int y=1900);
void setDate(int, int, int);
Date &operator++(void);//prefix increment. Like ++Date. And void is the sign for this function.
Date operator++(int);//postfix increment. Like Date++. And int is the sign for this function.
Date &operator+=(int);
bool leapYear(int) const;
bool endOfMonth(int) const;
void helpIncrement();
void setDays();
private:
int month;
int day;
int year;
int days[13];
};
#endif
//Date.cpp
#include "Date.h"
Date::Date(int m, int d, int y)
{
setDays();
setDate(m, d, y);
}
void Date::setDate(int m, int d, int y)
{
month = (m>=1&&m<=12)?m:1;
year = (y>=1&&y<=2200)?y:1900;
if (month==2&&leapYear(year))
day = (d>=1&&d<=29)?d:1;
else
day = (d>=1&&d<=days[month])?d:1;
}
Date &Date::operator ++(void)//!!!!!!!!!!!!!!!!!!!!!
{
helpIncrement();
return *this;
}
Date Date::operator ++(int)//!!!!!!!!!!!!!!!!!!!!!
{
Date temp = *this;
helpIncrement();
return temp;
}
Date &Date::operator +=(int n)
{
for (int i=0;i<n;i++)
helpIncrement();
return *this;
}
bool Date::leapYear(int y) const
{
if (y%400==0||(y%100!=0&&y%4==0))
return true;
else
return false;
}
//perfect!!!!!!!
bool Date::endOfMonth(int d) const
{
if (month==2&&leapYear(year))
return d==29;
else
return d==days[month];
}
void Date::helpIncrement()
{
if (!endOfMonth(day))
day++;
else
{
if (month<12)
{
month++;
}
else
{
year++;
month=1;
}
day=1;
}
}
void Date::setDays()
{
days[0]=0;
days[1]=31;
days[2]=28;
days[3]=31;
days[4]=30;
days[5]=31;
days[6]=30;
days[7]=31;
days[8]=31;
days[9]=30;
days[10]=31;
days[11]=30;
days[12]=31;
}
ostream &operator<<(ostream &output, const Date &date)
{
output<<date.month<<" "<<date.day<<" "<<date.year<<endl;
return output;
}
//run.cpp
#include<iostream.h>
#include "Date.h"
void main()
{
Date d1;
Date d2(12,27,1992);
Date d3(0,99,2132);
cout<<"d1 is "<<d1<<endl;
cout<<"d2 is "<<d2<<endl;
cout<<"d3 is "<<d3<<endl;
cout<<"/n/nd2 += 7 is "<<(d2+=7);
d3.setDate(2,28,1992);
cout<<"/n/nd3 is "<<d3;
cout<<"/n++d3 is "<<++d3;
Date d4(7,13,2002);
cout<<"d4 is "<<d4<<endl;
cout<<"++d4 is "<<++d4<<endl;
cout<<"d4 is "<<d4<<endl;
cout<<"d4++ is "<<d4++<<endl;
cout<<"d4 is "<<d4<<endl;
}
重载的前置自增运算符返回当前的Date对象的引用,也就是刚刚自增后的对象(例如:cout<<++n,输出n+1。而cout<<n++,输出n)。因为当前对象*this是作为Date&返回的,这使前置自增的Date对象可以作为左值来使用,正如内置的前置自增运算符对基本类型的工作方式。
重载的后置自增运算符更复杂一些。为了仿制内置的后置自增运算的效果,我们必须返回Date对象自增之前的一份副本。所以在函数中,把*this保存到temp中。然后再调用helpIncrement递增当前的Date对象。最后返回temp中的对象自增前的副本。
注意:该函数不能返回局部Date对象temp的引用,因为局部变量在其声明所在的函数退出时便销毁了。
Date &operator++(void)与Date operator++(int),为了使编译器区别两个函数,一个传入参数为(void),另一个是(int)。
实际上重载前置自增运算符与后置自增运算符完全遵循内置的运算规律。换句话说,重载前置自增运算符与后置自增运算符只要理解性的记下来就好。