学习函数模板的使用方法,包括以下几个方面:
(1)学习为什么要使用模板,掌握函数模板的定义方法;
(2)理解函数模板实例化的原理。
定义一个求最大值的函数模板,可以求出一个下列数组中的最大者。
(1)点(Point)对象数组。对《实验三 面向对象初步》中的Point类进行适当修改,通过调用函数模板,求出数组中离坐标系原点最远的点。请使用Point对象的distanceTo函数。
(2)日期(Date)对象数组。对《实验三 面向对象初步》中的Date类进行适当修改,通过调用函数模板,求出数组中最晚的日期。
(3)雇员对象(Employee)对象数组。对《实验四 对象作为数据成员》中的Employee类进行适当修改,通过调用函数模板,求出数组中年龄最大的雇员。
提示:需要对每个类的“>”运算符进行重载。
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include
#include"Date.h"
using namespace std;
class Employee
{
public:
Employee(string firstName, string lastName, Date birthDate, Date hireDate);
static const Employee& getMostFaith(const Employee employees[], int n);
void print();
int getAge(Date& date);
int getYearsWorked(Date& date);
int getDaysWorked(Date& date);
bool operator<(Employee& employee);
~Employee() {} //析构函数
private:
string lastName;
string firstName;
Date birthDate; //内嵌对象,出生日期
Date hireDate; //内嵌对象,雇用日期
};
#endif
#include"Employee.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const Employee& Employee::getMostFaith(const Employee employees[], int n)
{
int mi = 0;
for (int i = 1; i < n; i++)
{
if (employees[mi].hireDate > employees[i].hireDate)
{
mi = i;
}
}
return employees[mi];
}
Employee::Employee(string firstName, string lastName, Date birthDate, Date hireDate) {
this->firstName = firstName;
this->lastName = lastName;
this->birthDate = birthDate;
this->hireDate = hireDate;
}
void Employee::print()
{
cout << lastName << ", " << firstName << " Hired:";
hireDate.printFullYear();
cout << " Birthday: ";
birthDate.printFullYear();
}
int Employee::getAge(Date& date)
{
return birthDate.fullYearsTo(date);
}
int Employee::getYearsWorked(Date& date)
{
return hireDate.fullYearsTo(date);
}int Employee::getDaysWorked(Date& date)
{
return date - hireDate;
}
int operator-(Date& da, Date& date)
{
int ans = 0;
if (da.getYear() < date.getYear())
{
for (int i = da.getYear() + 1; i < date.getYear(); i++)
{
if (da.isLeapyear(i))
{
ans += 366;
}
else
{
ans += 365;
}
}
ans = ans + da.getLeftDaysYear() + date.getDayOfYear();
}
else if (da.getYear() > date.getYear())
{
for (int i = date.getYear() + 1; i < da.getYear(); i++)
{
if (da.isLeapyear(i))
{
ans -= 366;
}
else
{
ans -= 365;
}
}
ans = ans - date.getLeftDaysYear() - da.getDayOfYear();
}
else
{
if (da.isLeapyear(da.getYear()))
{
ans = 366 - da.getDayOfYear() - date.getLeftDaysYear();
}
else
{
ans = 365 - da.getDayOfYear() - date.getLeftDaysYear();
}
}
return -ans;
}
bool Employee::operator<(Employee& employee) {
return employee.birthDate < this->birthDate;
}
#ifndef DATE_H
#define DATE_H
class Date
{
friend int operator-(Date& da, Date& date);
public:
Date(int year = 1990, int month = 1, int day = 1);
void setDate(int year, int month, int day);
void setYear(int year);
int getYear();
void setMonth(int month);
int getMonth();
void setDay(int day);
int getDay();
void setSeparator(char separator);
void printFullYear();
void printStandardYear();
int fullYearsTo(Date& date);
bool operator<(const Date& da) const;
bool operator>(const Date& da) const;
int getDayOfYear();
int getLeftDaysYear();
bool isLeapyear(int year);
private:
int year;
int month;
int day;
char separator;
static int days[13];
int checkDay(int day);
};
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"Date.h"
using namespace std;
Date::Date(int year , int month , int day )
{
this->year = year;
this->month = month;
this->day = day;
this->separator = '-';
}
/* get、set方法 */
// 设置日期,如果有非法的月或日,将其置为1
void Date::setDate(int year, int month, int day)
{
if (year >= 0)
{
this->year = year;
}
else
{
this->year = 1;
}
if (isLeapyear(year))
{
days[2] = 29;
}
else
{
days[2] = 28;
}
if (month > 12 || month < 1)
{
this->month = 1;
this->day = 1;
}
else if (day < 1 || day > days[month])
{
this->day = 1;
}
else
{
this->day = day;
}
}
void Date::setYear(int year)
{
if (year >= 0)
{
this->year = year;
}
else
{
this->year = 1;
}
}
int Date::getYear()
{
return this->year;
}
void Date::setMonth(int month)
{
if (month > 0 && month <= 12)
{
this->month = month;
}
else
{
this->month = 1;
}
}
int Date::getMonth()
{
return this->month;
}
void Date::setDay(int day)
{
this->day = checkDay(day);
}
int Date::getDay()
{
return this->day;
}
void Date::setSeparator(char separator)
{
this->separator = separator;
}
/* 输出函数,请使用setfill(‘0’)和setw(2),需要包含头文件 */
void Date::printFullYear()
{
cout << setw(4) << this->year << this->separator << setw(2) <<
setfill('0') << this->month << this->separator << setw(2) << setfill('0') <<
this->day;
}
void Date::printStandardYear()
{
int yy = this->year % 100;
cout << setw(4) << setfill(' ') << yy << this->separator << setw(2) <<
setfill('0') << this->month << this->separator << setw(2) << setfill('0') <<
this->day;
cout << endl;
} // 以YY-MM-DD的形式打印,比如11-01-08
/* 计算函数 */
// 计算当前日期与参数日期之间相差几个整年,仅考虑参数日期比当前日期晚的情况
int Date::fullYearsTo(Date& date)
{
int ans = date.getYear() - this->year;
if (this->month > date.getMonth())
{
ans--;
}
else if (this->month == date.getMonth())
{
if (this->day > date.getDay())
{
ans--;
}
}
return ans;
}
/* 计算当前日期与参数日期之间相差多少天(考虑闰年),如果参数日期在当前日期之前,返回负数。
*/bool Date::operator<(const Date& da) const
{
bool ans;
if (year < da.year)
{
ans = true;
}
else if (year > da.year)
{
ans = false;
}
else
{
if (month < da.month)
{
ans = true;
}
else if (month > da.month)
{
ans = false;
}
else
{
if (day < da.day)
{
ans = true;
}
else
{
ans = false;
}
}
}
return ans;
}
bool Date::operator>(const Date& da) const
{
bool ans;
if (year > da.year)
{
return true;
}
else if (year < da.year)
{
return false;
}
else {
if (month > da.month)
{
return true;
}
else if (month < da.month)
{
return false;
}
else
{
if (day > da.day)
{
return true;
}
else
{
return false;
}
}
}
return ans;
}
int Date::getDayOfYear()
{
int ans = 0;
if (isLeapyear(year))
{
days[2] = 29;
}
else
{
days[2] = 28;
}
for (int i = 1; i < month; i++)
{
ans += days[i];
}
return ans + day;
} //计算当前日期是本年的第几天
int Date::getLeftDaysYear()
{
if (isLeapyear(year))
{
return 366 - getDayOfYear();
}
else
{
return 365 - getDayOfYear();
}
} //计算当前日期距本年结束还有几天,不包括当前日期这一天
bool Date::isLeapyear(int year)
{
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
return true;
}
else
{
return false;
}
}
int Date::checkDay(int day)
{
if (isLeapyear(year))
{
days[2] = 29;
}
else
{
days[2] = 28;
}
if (day < 1 || day > days[month])
{
return 1;
}
else
{
return day;
}
}
int Date::days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
#ifndef POINT_H
#define POINT_H
class Point {
public:
Point(int x = 0, int y = 0);
void setX(int x);
int getX();
void setY(int y);
int getY();
void print();
void moveRight(int offset);
void moveDown(int offset);
double distanceTo(int a, int b);
bool operator<(Point & p);
private:
int x;
int y;
};
#endif
#include"Point.h"
#include
using namespace std;
Point::Point(int x , int y ) {
this->x = x;
this->y = y;
};
void Point::setX(int x) {
this->x = x;
}
void Point::setY(int y) {
this->y = y;
}
int Point::getY() {
return this->y;
}
int Point::getX() {
return this->x;
}
void Point::moveRight(int offset) {
this->x += offset;
}
void Point::moveDown(int offset) {
this->y += offset;
}
void Point::print() {
cout << '(' << this->x << ',' << this->y << ')' << endl;
}
double Point::distanceTo(int a, int b) {
return sqrt((x - a) * (x - a) + (y - b) * (y - b));
}
bool Point::operator<(Point& p) {
if (distanceTo(0, 0) < p.distanceTo(0, 0)) {
return true;
}
else {
return false;
}
}
#include
#include"Date.h"
#include"Employee.h"
#include"Point.h"
using namespace std;
template<class T>
T& Mymax(T* a, T* b) {
T* mx = a;
a++;
while (a <= b) {
if (*mx < *a) {
mx = a;
}
a++;
}
return *mx;
}
int main() {
Point point[4] = { {1,2},{5,6},{2,2} ,{3,1} };
cout << "这里有四个Point,它们分别是:\n";
for (int i = 0; i <= 3; i++) {
point[i].print();
}
cout << "\n距离零点最远的点是:\n";
Mymax(point, point + 3).print();
cout << "\n\n\n这里有四个Date,它们分别是:\n";
Date dates[4] = { Date(2000, 7, 2), Date(1964, 11, 2), Date(1969, 9, 9), Date(2002, 5, 5) };\
for (int i = 0; i <= 3; i++) {
dates[i].printFullYear();
cout << endl;
}
cout << "\n最晚的Date是:\n";
Mymax(dates, dates + 3).printFullYear();
cout << "\n\n\n\n这里有四名Employee,他们分别是:\n";
Employee employees[4] = {
Employee("火花骑士", "可莉", Date(2012, 1, 10), Date(2020,9 ,15)),
Employee("风神", "巴巴托斯", Date(1207, 6, 13), Date(2020,9 ,15)),
Employee("蒲公英骑士", "琴", Date(1995, 2, 3), Date(2020,9 ,15)),
Employee("白垩之子", "阿贝多", Date(2000, 4, 23), Date(2020,9 ,15))
};
for (int i = 0; i <= 3; i++) {
employees[i].print();
cout << endl;
}
cout << "\n其中年龄最大的是:\n";
Mymax(employees, employees + 3).print();
cout << endl;
}