【C++】声明并实现一个万年历类【腾讯面试题】

一、万年历类中所包含函数,以及功能

/******************************************************************************************

Date.hpp:

Copyright (c) Bit Software, Inc.(2013), All rights reserved.

Purpose:

声明并实现一个万年历类【腾讯面试题】

Author:

xxx

Created Time:

2015-4-26

******************************************************************************************/

class Time

{

public:

Time(int hour);

Time(const Time& t);

Time& operator=(const Time& t);

private:

int _hour;

}

class Date

{

public:

// 初始化列表进行初始化。

Date (int year = 1900, int month = 1, int day = 1);

Date (const Date& d);

Date& operator= (const Date& d);

void Display ();

public:

//

// 比较日期的运算符重载

//

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

//

// 计算一个日期加减一个天数以后的日期。

//

Date operator+(int day);

Date operator-(int day);

Date& operator-=(int day);

Date& operator+=(int day);

const Date& operator++();
// 前置++

Date operator++(int);
// 后置++

const Date& operator--();
// 前置--

Date operator--(int);
// 后置--

//

// 两个日期相加没有意义

// 计算两个日期相减以后的差的天数

//

int operator-(const Date& d);

private:

int _year;

int _month;

int _day;

const int _testConst;

int& _testRef;

Time _t;

};

二、代码

#include <iostream>
using namespace std;

class Time
{
public:
	Time(int hour=0,int minute=0,int second=0)
	{
		//cout<<"构函数"<<endl;
		_hour=hour;
		_minute=minute;
		_second=second;
	}

	friend class Date;

	Time(const Time& t)
	{
		//cout<<"copy构造函数"<<endl;
	}

	Time& operator=(const Time& t)
	{
		_hour = t._hour;
		_minute=t._minute;
		_second=t._second;

		return *this;
	}

private:
	int _hour;
	int _minute;
	int _second;
};

class Date
{
public:
	// 初始化列表进行初始化
	//Date (int year = 1900, int month = 1, int day = 1,int hour=0):_t(hour)
	//{
	////	cout<<"构造函数"<<endl;
	//	_year = year;
	//	_month = month;
	//	_day = day;

	//	if (CheckDate() == false)
 //        {
 //           Date();
 //        }

	//}
	Date (int year = 1900, int month = 1, int day = 1)
		:_year(year)
		,_month(month)
		,_day(day)
	{
		// 检查如果输入参数是非法时间,则初始化为1900-1-1
		if (CheckDate())
		{
			year = 1900;
			month = 1;
			day = 1;
		}
	}

	Date (const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		//cout<<"copy构造函数"<<endl;
	}

	Date& operator= (const Date& d)

	{
		_year=d._year;
		_month=d._month;
		_day=d._day;
		return *this;
	}

	void Display (Time& t)
	{
		cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
		cout<<t._hour<<":"<<t._minute<<":"<<t._second<<endl;
	}

public:

	//日期检查
	bool CheckDate ()
    {
          if (_year < 1
             || ( _month < 1 || _month > 12)
             || ( _day < 1   || _day > MonthDay(_year, _month )))
         {
              return true ;
         }

          return false ;
    }

	//
	// 比较日期的运算符重载
	//
	bool operator == (const Date& d)
	{
		return(_year == d._year) && (_month == d._month) && (_day == d._day);
	}

	bool operator != (const Date& d)
	{
		return !(*this == d);
	}

	bool operator > (const Date& d)
	{
		if(_year > d._year)
		{
			return true;
		}
		else if((_year == d._year)&&(_month > d._month))
		{
			return true;
		}
		else if((_year == d._year)&&(_month == d._month)&&(_day >d._day))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	bool operator >= (const Date& d)
	{
		return ((*this==d)||(*this>d));
	}

	bool operator < (const Date& d)
	{
		return !(*this>=d);

	}

	bool operator <= (const Date& d)
	{
		return !(*this>d);
	}

	// 将日期转换为正确的日期
	//注意此函数功能多次用到,因此进行单个包装,用来减短代码长度!!!
	void _ToCrrectDate()
	{
		while(_day < 0)
		{
			_day += MonthDay (_year, _month);

			if (_month == 1)
			{
				_year--;
				_month = 12;
			}
			else
			{
				_month--;
			}
		}

		while (_day > MonthDay(_year, _month))
		{
			_day -= MonthDay (_year, _month);

			if (_month == 12)
			{
				_year++;
				_month = 1;
			}
			else
			{
				_month++;
			}
		}
	}

	//
	// 计算一个日期加减一个天数以后的日期。
	//
	Date operator+(int day)
	{
		Date tmp(*this);
		tmp._day+=day;
		tmp._ToCrrectDate();

		return tmp;
	}

	Date operator-(int day)
	{

			Date tmp(*this);
			tmp._day=tmp._day-day;
			tmp._ToCrrectDate();
			return tmp;
	}

	Date& operator-=(int day)
	{
		this->_day -= day;
		this->_ToCrrectDate();
		return *this;
	}

	Date& operator+=(int day)
	{
		this->_day += day;
		this->_ToCrrectDate();
		return *this;
	}

	const Date& operator++()	// 前置++
	{
		*this += 1;
		return *this;
		return *this;
	}

	Date operator++(int)		// 后置++		若没有加上(int),为何有如此多的错误
	{
		Date tmp(*this);
		*this += 1;
		return tmp;
	}

	const Date& operator--()	// 前置--
	{
		*this -= 1;
		return *this;
	}

	Date operator--(int)		// 后置--
	{
		Date tmp(*this);
		*this -= 1;
		return tmp;
	}
	//
	// 两个日期相加没有意义
	// 计算两个日期相减以后的差的天数
	//
	int operator-(const Date& d)
	{
		int flag = 1;			//标示量
		Date x1 = *this, x2 = d;
		if (x1 < x2)
		{
			flag = -1;
			x1 = d;
			x2 = *this;
		}

		int Days = 0;		//日期相差天数
		while (x1 != x2)
		{
			++x2;
			Days++;
		}

		return Days*flag;
	}

	int MonthDay(int year,int month)
	{
		if (year < 1 || month < 1 || month > 12)
		{
              return 0;
        }
		static int array[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};	//注意static的作用
		if(((year%4)&&(year%100)!=0)||(year%400==0))
		{
			array[2]=28;
		}
		return array[month];
	}

	friend ostream& operator<<( ostream& os , const Date& d );

    friend istream& operator>>( istream& is , Date& d);

private:
	int _year;
	int _month;
	int _day;

	/*const int _testConst;
	int& _testRef;*/
	Time _t;
};

ostream& operator<<( ostream& os , const Date& d )
{
	os<<d._year<<"-";
	os<<d._month<<"-";
	os<<d._day;

     return os ;
}

istream& operator>>( istream& is , Date& d)
{
     cout<<" 请分别输入年月日: "<<endl ;
     is>>d._year;
     is>>d._month;
     is>>d._day;

     return is ;
}

void PromptInfo()
{
	cout<<"========日期计算器======="<<endl;
	cout<<"0.退出"<<endl;
	cout<<"1.推后几天的日期"<<endl;
	cout<<"2.计算日期差"<<endl;
	cout<<"3.清屏"<<endl;
	cout<<"========================="<<endl;
}

void main()
{
	Date d1, d2;
	int in, days;
	do {
		PromptInfo();
		cin>>in;

		switch(in)
		{
		case 0:
			break;
		case 1:
			cin>>d1;
			if (d1.CheckDate())
			{
				cout<<"输入日期非法!"<<endl;
				break;
			}
			cout<<"请出入计算推后的天数"<<endl;
			cin>>days;
			d1+=days;
			cout<<d1<<endl;
			break;
		case 2:
			cin>>d1;
			if (d1.CheckDate())
			{
				cout<<"输入日期非法!"<<endl;
				break;
			}
			cin>>d2;
			if (d2.CheckDate())
			{
				cout<<"输入日期非法!"<<endl;
				break;
			}
			days = d1 - d2;
			cout<<"相差的天数:"<<days<<endl;
			break;
		case 3:
			 system("CLS");
			 break ;
		default:
			cout<<"选项错误,请重新选择"<<endl;
			break;
		}
	}while(in != 0);
	getchar();
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 17:07:05

【C++】声明并实现一个万年历类【腾讯面试题】的相关文章

C++ 声明并实现一个复数类

<pre name="code" class="cpp">/****************************************************************************************** complex.hpp: Copyright (c) Bit Software, Inc.(2013), All rights reserved. Purpose: 声明并实现一个复数类 难度:** Author:

Java语言程序设计 上机实验4 掌握声明接口、一个类实现接口的声明和使用方法

Java语言程序设计 上机实验4 实验目的: 理解接口的作用,理解接口和实现接口的类的关系,掌握声明接口.一个类实现接口的声明和使用方法:熟悉Java语言包和实用包中的常用类. 实验内容:(*)为选做 声明圆柱体类Cylinder,继承椭圆类Ellipse(实现周长Perimeter接口和面积Area接口),为圆柱体类设计较为全面的构造方法,并实现体积Volume接口,计算表面积和体积. 将Java的若干关键字(15个以上)保存在一个字符串数组中,对其按升序排列,再采用顺序查找和二分法查找,判断

声明一个MyClass类,在类中声明一个常量,和一个成员方法

<?php class MyClass { //声明一个MyClass类,在类中声明一个常量,和一个成员方法 const CONSTANT = 'CONSTANT value'; //使用const声明一个常量,并直接赋上初使值 private $foo; private $sss; function __construct($foo,$sss){ $this->foo = $foo; $this->sss = $sss; } function showConstant() { //声明

PHP用单例模式实现一个数据库类

使用单例模式的出发点: 1.php的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 使用单例模式, 则可以避免大量的new 操作消耗的资源. 2.如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现. 这个可以参看ZF的FrontController部分. 3.在一次页面请求中, 便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中, 我们可以在类中设置钩子, 输出日志,从而避免到处var_dump, echo. 创造单例注意: 1

一个数组类【模板类】

这学期的大作业感觉挺简单的,就是写一个模板类MyList,实现一些Python中的list的操作(类似于c++中的vector,但是不支持迭代器).这些功能都很简单,唯一麻烦的就是模板类特别烦,特别是友元函数,首先要声明这个类,然后声明是函数的声明,然后是类中友元函数的声明,最后是实现.友元函数的声明还有一个问题就是声明时在函数名后面要加上一个<>就像这样: friend void Qsort<>(T a[],int low,int high,bool less); 还有一个要注意

小结在一个java源文件当中可以有多个类,但是为什么只能有一个public类呢?而当这个类被修饰为public的话,为什么源文件名必须要与类名相同呢?

Java编程思想中的一段话: 当编写一个java源代码文件时,此文件通常被称为编译单元(有时也被称为转译单元).每个编译单元都必须有一个后缀名.java,而在编译单元内则可以有一个public类,该类的名称必须与文件的名称相同(包括大小写,但不包括文件的后缀名.java).每个编译单元只能有一个public类,否则编译器就不会接受.如果在该编译单元之中还有额外的类的话,那么在包之外的世界是无法看见这些类的,这是因为它们不是public类,而且它们主要用来为主public类提供支持. 理解: 每编

《黑吗程序员》OC的认识和第一个OC类

面向对象和面向过程的区别 ① oc是面向对象 ② c是面向过程 ③  面向对象和面向过成只不过是解决问题的两种不同的思路 ④  面向过程只不过是考虑问题解决的步骤,面向对象只不过是考虑解决问题需要的对象. OC 类的认识      类的设计必须关心三样事物: ① 类名 ② 属性 ③ 行为 类名:所有的名词都是类名,且类名的第一个字母必须大写. 如果类名有多个名词,要使用驼峰标示. 属性:代表这个类在创建出来所拥有的的属性. 行为: 这个类所拥有的功能. 类的创建 // 类的声明 @interfa

一个java源文件中为什么只能有一个public类。

我们都遇到过一个源文件中有多个java类,但当第一个类使用public修饰时,如果下面还有类使用public修饰,会报错.也就是是说一个java源文件最多只能有一个public类. 当有一个public类时,源文件名必须与之一致,否则无法编译,如果源文件中没有一个public类,则文件名与类中没有一致性要求. java虚拟机实例通过调用某个类的main()来运行一个Java程序,而这个main()必须是public static void 并接收一个字符串数组作为参数,任何拥有这样一个main(

浅谈为什么一个java源文件中只能有一个public类?

声明,本篇文章为转载 转载 http://blog.csdn.net/bareheadzzq/article/details/6562211 最近在一个java文件中实现了几个类,其中一个声明为public类型,但编译器报错:后来将public去掉,也即文件中没有一个public类,程序正常运行,有些困惑,最后通过本文章找到答案,为以后方便查找,转载,感谢作者. 结论: 一个Java源文件中最多只能有一个public类,当有一个public类时,源文件名必 须与之一致,否则无法编译,如果源文件中