//13.4 抽像类做界面(Abstract Class As Interface)
//13.4.1 抽像基类方案(The Abstract Base-Class Scheme)
//13.4.2 抽像基类IDate(Abstract Base-Class IDate)
//我们针Date类的公有成员函数提取出来做成纯虚函数,构成一个抽像类IDate,而Date类则继承之
//13.4.3 创建Date对像(Creating Date Objects)
//13.4.4 子类Date(Subclass Date)
//为了适应抽像类作为界面的形式,Date类应包含idate.h文件,直接继承IDate类,并且在date.cpp中还要实现创建Date对像的三个create
//Date_three类由IDate_new派生
#include "idate_new.h" //#include "idate_three.h"; #include <iostream> void fn(IDate_new &d1, IDate_new& d2) { std::cout<<d2-d1<<"\n"; std::cout<<++d1; } //感觉C++的机制太神奇了,可以直接虚类访问数据,直接用几个函数就行了, //算不上会了,但也算见识过了 int main() { IDate_new& rd1 = createDate(2005,1,6); IDate_new& rd2 = createDate(2005,2,3); fn(rd1,rd2); delete &rd1; delete &rd2; system("pause"); return 0; }
#include <iostream> class IDate_new { protected: //定义一个保护的纯虚函数 virtual int ymd2i()const = 0; public: virtual ~IDate_new(){} virtual IDate_new& operator+(int n) = 0; //virtual int operator-(const IDate_new& d){ return ymd2i() - d.ymd2i(); } int operator-(const IDate_new& d){ return ymd2i() - d.ymd2i(); } virtual IDate_new& operator+=(int n) = 0; virtual IDate_new& operator++()=0; virtual void print(std::ostream& o)const = 0; }; IDate_new& createDate(int y, int m, int d); IDate_new& createDate(int n); IDate_new& createDate(const std::string s); inline std::ostream& operator<<(std::ostream& o, const IDate_new& d){ d.print(o); return o; }
#include "idate_new.h" #include <iostream> class IDate_three : public IDate_new { int year, month, day; protected: int ymd2i()const; //设置纯函数 void i2ymd(int n); //自已定义的函数 static const int tians[]; //bool isLeapYear()const{ return (year%4==0 || year%400==0) && year%100 !=0; } bool isLeapYear()const{ return !(year%4)&&(year%100)||!(year%400); } public: IDate_three(const std::string s); IDate_three(int n){ i2ymd(n); } IDate_three(int y, int m, int d):year(y),month(m),day(d){} ~IDate_three(){} IDate_three& operator+(int n){ return *new IDate_three(ymd2i()+n); } IDate_three& operator+=(int n){ i2ymd(ymd2i()+n); return *this; } IDate_three& operator++() { return *this +=1;} void print(std::ostream& o)const; };
#include "idate_three.h" #include <iostream> #include <iomanip> using namespace std; const int IDate_three::tians[]={0,31,59,89,120,150,181,212,242,273,303,334}; IDate_three::IDate_three(const string s) { year = atoi(s.substr(0,4).c_str()); month = atoi(s.substr(5,2).c_str()); day = atoi(s.substr(8,2).c_str()); } void IDate_three::i2ymd(int absDay) { absDay = absDay>0 && absDay<3650000 ? absDay : 1; int n = absDay; for(year=1; n>isLeapYear()+365; n-=isLeapYear()+365, year++); //条件为month 小于12,并且n必须大于当前month月的天数,还有month大于二月; 月份加加 for(month=1; (month<12 && n>(isLeapYear() && month>2)+tians[month]); month++); //取得天数,减去月份的天数,在减去二月是否闰月的天数 day = n-(isLeapYear() && month>2)-tians[month-1]; } int IDate_three::ymd2i()const{ //取得年的天数, 取得所有闰年的天数 在减去100整数不为闰年的数据,在加上400的闰年数 int absday = (year-1)*365 + (year-1)/4 - (year-1)/100 + (year-1)/400; return absday += tians[month-1] + (isLeapYear() && month>2) + day; } void IDate_three::print(ostream& o)const{ o<<setfill('0')<<setw(4)<<year<<"-"<<setw(2)<<month<<"-"<<setw(2)<<day<<"\n"<<setfill(' '); } //错误出现在这里,因为这里只是重载一下idate_new中的函数 //太不小心了,把他当一种类型的重载了 IDate_new& createDate(int y, int m, int d){ return *new IDate_three(y,m,d); } IDate_new& createDate(int n){ return *new IDate_three(n); } IDate_new& createDate(const string s){ return *new IDate_three(s); }