13.4 抽像类做界面(Abstract Class As Interface)

//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);
}

  

posted @ 2012-02-16 23:23  简单--生活  阅读(255)  评论(0编辑  收藏  举报
简单--生活(CSDN)