1 实验目的
学习对象作为类的数据成员的使用方法,学习对象数据成员的初始化以及“初始化列表”的使用方法。
2 实验内容
2.1 使用Date类,定义Employee类
(1)问题描述
在《实验三 面向对象初步》中,设计了日期类Date。本次实验将设计雇员类Employee,并将日期类Date作为雇员类Employee的内嵌数据成员。日期类Date和雇员类Employee的声明分别如下所示:
class Date {
public:
/* 默认构造函数,以fullyear的形式给出年月日,默认值为1990年1月1日,同时设置日期分隔符为“-” */
Date(int year = 1990, int month = 1, int day = 1);
/* get、set方法 */
// 设置日期,如果有非法的月或日,将其置为1
void setDate(int year, int month, int day);
void setYear(int year);
int getYear();
void setMonth(int month);
int getMonth();
void setDay(int month);
int getDay();
void setSeparator(char separator);
/* 输出函数,请使用setfill(‘0’)和setw(2)。*/
void printFullYear(); //以YYYY-MM-DD的形式打印,2011-01-08
void printStandardYear(); //以YY-MM-DD的形式打印,比如11-01-08
/* 计算当前日期与参数日期之间相差几个整年,仅考虑参数日期比当前日期晚的情况。注意参数为日期对象的引用。*/
int fullYearsTo(Date &date);
/* 计算当前日期与参数日期之间相差多少天(考虑闰年),如果参数日期在当前日期之前,返回负数。注意参数为日期对象的引用。*/
int daysTo(Date &date);
/* 新增函数,可以被daysTo函数调用 */
int getDayOfYear(); //计算当前日期是本年的第几天
int getLeftDaysYear(); //计算当前日期距本年结束还有几天,不包括当前日期这天
private:
int year;
int month;
int day;
char separator; // 日期分隔符
/* 新增数据成员和函数成员 */
/*声明静态常变量,每月的天数,在.cpp文件中定义并初始化 */
static const int DAYS_PER_MONTH[12];
/*根据年和月,判断参数日期是否合法。如果合法,返回day,否则返回-1。*/
int checkDay(int day);
bool isLeapyear(int year);//断参数年是否是闰年。
};
const int Date::DAYS_PER_MONTH[12] = {31, 28, 31, ……};
class Employee{
public:
//构造函数,使用“初始化列表”初始化数据成员
Employee(string, string, Date &, Date &);
//打印员工的信息。调用Date类的print函数,打印员工的生日和雇佣日期。
void print();
//计算员工在参数指定的日期时,满多少岁。请使用Date类的fullYearsTo函数
int getAge(Date &date);
//计算该员工在参数指定的日期时,工作满了多少年。
int getYearsWorked(Date &date);
//计算该员工在参数指定的日期时,工作了多少天。使用Date类的daysTo函数。
int getDaysWorked(Date &date);
~Employee(); //析构函数
private:
string firstName;
string lastName;
Date birthDate; //内嵌对象,出生日期
Date hireDate; //内嵌对象,雇用日期
};
(2)问题要求
可以满足以下主函数的要求:
#include
#include
using namespace std;
void main() {
Date birth(1969, 8, 11);
Date hire(1998, 4, 1);
Date today(2010, 4, 30);
Employee manager(“Bob”, “Blue”, birth, hire);
cout << endl;
manager.print();
cout << endl;
cout << manager.getAge(today) << endl;
cout << manager.getDaysWorked(today) << endl;
}
输出结果如下,其中的注释仅为了说明运行结果,实际执行时不必输出。
//调用manager.print()后,打印以下信息
Blue, Bob Hired: 1998-04-01 Birthday: 1969-08-11
//调用manager.getAge(today)后,打印以下信息
40 // 工作满了40年
//调用manager.getDaysWorked(today)
4412 // 已工作了4412天
源代码如下:
#include<iostream>
#include<string>
#include<iomanip>
using namespace std;
class Date {
public:
Date(int year = 1990, int month = 1, int day = 1); //构造函数
void setDate(int year, int month, int aday);
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);
int daysTo(Date& date);
int getDayOfYear();
int getLeftDaysYear();
int getYearDays(int year);
private:
int year;
int month;
int day;
char separator;
static const int DAYS_PER_MONTH[12];
int checkDay(int day);
bool isLeapyear(int year);
};
const int Date::DAYS_PER_MONTH[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
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 (day > 0 && day <= DAYS_PER_MONTH[month - 1])
return day;
if (isLeapyear(year) && month == 2 && day == 29)
return day; //正确的话返回当月的天数
cout << "Invalid day(" << day << ")set to 1.\n"; //不正确的话返回1
return 1;
}
Date::Date(int year, int month, int day) {
this->year = year;
this->month = month;
this->day = day;
this->separator = '-';
}
void Date::setYear(int year) {
this->year = year;
}
int Date::getYear() {
return year;
}
void Date::setMonth(int month) {
this->month = month;
}
int Date::getMonth() {
return month;
}
void Date::setDay(int day) {
this->day = day;
}
int Date::getDay() {
return day;
}
void Date::setSeparator(char separator) {
this->separator = separator;
}
void Date::printFullYear() {
cout << year << separator << setfill('0') << setw(2) << month << separator << setfill('0') << setw(2) << day ;
}
void Date::printStandardYear() {
cout << setfill('0') << setw(2) << year % 100 << separator << setfill('0') << setw(2) << month << separator << setfill('0') << setw(2) << day;
}
int Date::fullYearsTo(Date& date) {
if (this->month < date.month || (this->month == date.month && this->day <= date.day))
return date.year - this->year;
else
return date.year - this->year - 1;
}
int Date::getDayOfYear() {
int days = 0;
int i;
for (i = 1; i < month; i++)
days += DAYS_PER_MONTH[month - 1];
days += day;
if (isLeapyear(year) && month > 2)
days++;
return days;
}
int Date::getYearDays(int year) {
if (isLeapyear(year))
return 366;
else
return 365;
}
int Date::getLeftDaysYear() {
return getYearDays(year) - getDayOfYear();
}
int Date::daysTo(Date& date) {
int days;
if (this->year == date.year)
return date.getDayOfYear() - this->getDayOfYear();
else if (this->year < date.year)
{
days = this->getLeftDaysYear() + date.getDayOfYear();
for (int i = this->year + 1; i < date.year; i++)
days = days + getYearDays(i);
return days;
}
else {
days = date.getLeftDaysYear() + this->getDayOfYear();
for (int i = date.year + 1; i < this->year; i++)
days += getYearDays(i);
return 0 - days - 1;
}
}
class Employee {
public:
Employee(string, string, Date&, Date&);
void print();
int getAge(Date& date);
int getYearsWorked(Date& date);
int getDaysWorked(Date& date);
//~Employee();
private:
string firstName;
string lastName;
Date birthDate;
Date hireDate;
};
Employee::Employee(string firstName, string lastName, Date& birth, Date& hire) {
this->firstName = firstName;
this->lastName = lastName;
this->birthDate = birth;
this->hireDate = hire;
}
int Employee::getAge(Date& date) {
return birthDate.fullYearsTo(date);
}
void Employee::print() {
cout << lastName << "," << firstName << " Hired: " ;
hireDate.printFullYear();
cout << " Birthday: ";
birthDate.printFullYear();
}
int Employee::getDaysWorked(Date& date) {
return hireDate.daysTo(date);
}
int main() {
Date birth(1969, 8, 11);
Date hire(1998, 4, 1);
Date today(2010, 4, 30);
Employee manager("Bob", "Blue", birth, hire);
cout << endl;
manager.print();
cout << endl;
cout << manager.getAge(today) << endl;
cout << manager.getDaysWorked(today) << endl;
}
2.2 设计一个CD播放机CDPlayer
(1)问题描述
设计一个CD播放机CDPlayer,它能够播放CD中的歌。其中,CD类、CDPlayer类的声明分别如下所示:
class CD {
public:
CD(string name, string songs[]);
string getSinger(); // 获得歌手的名称
string getSong(int index); // 获得某首歌的歌名
void listSongs(); // 列出CD的内容
private:
string singer; // 歌手的名字。
string songs[6]; // 每张专辑6首歌的名字。
};
class CDPlayer {
public:
CDPlayer();
/*提供给用户一个菜单,通过这个菜单,用户可以选择:
- 插入CD
- 播放CD
- 弹出CD
- 关机 */
void showMenu();
/插入CD. void insertCD(CD cd),形参是指向CD对象的指针。如果CDPlayer中已经有CD,提示先取出CD;如果CDPlayer中没有CD,显示插入了哪位歌星的CD。*/
void insertCD(CD *cd);
/弹出CD. CD ejectCD(),返回值是指向该CD对象的指针。如果CDPlayer中已经有CD,显示弹出了哪位歌星的CD,返回该CD的指针;如果CDPlayer中没有CD,提示CDPlayer中没有CD,返回NULL。/
CD ejectCD();
/播放CD。如果CDPlayer中已经有CD,显示正在播放哪位歌星的CD,并打印CD中歌曲的清单;如果CDPlayer中没有CD,显示CDPlayer中没有CD,并提示用户插入CD。/
void play();
private:
/ 插入CDPlayer中的CD,它是指向CD对象的指针。没有CD时,为null。使用指针,很好地模拟 了CD对象不是播放器的一部分,播放器只是读取放入其中的CD的内容。/
CD *cd;
bool cdIn; // CDPlayer中是否已经插入CD
};
主函数如下:
void main() {
string name;
string songs[6];
cout << “制造CD…” << endl;
// 输入歌手名字
cout << " Singer’s Name: " << endl;
cin >> name; // 输入:周杰伦
// 输入该歌手的六首歌名(青花瓷、菊花台、双节棍等)
for (int i = 0; i < 6; i++) {
cout << " song" << (i+1) << "#: ";
cin >> songs[i];
}
CD cd(name, songs); //制造CD
cd.listSongs(); //显示CD的内容
CDPlayer player; //制造CDplayer
player.showMenu(); //生成播放机的按钮
/* 播放 /
player.play(); //打印:Please insert CD first
/ 插入CD /
player.insertCD(&cd); //打印:插入了周杰伦的CD…
/ 播放 */
player.play(); //打印:正在播放周杰伦的CD…
player.ejectCD(); //打印:弹出了周杰伦的CD…
/* 另造一张CD,歌手和歌的录入省略。*/
CD cd2(name2, songs2);
player.insertCD(&cd2);
player.play();
}
(2)问题要求
程序的执行结果如下:
制造CD…
Singer’s Name: 周杰伦
song1#: 青花瓷
song2#: 菊花台
song3#: 双节棍
song4#: 东风破
song5#: 珊瑚海
song6#: 稻香
Singer: 周杰伦
- 青花瓷
- 菊花台
- 双节棍
- 东风破
- 珊瑚海
- 稻香
-
- 播放CD *
-
- 插入CD *
-
- 弹出CD *
-
- 关机 *
Please insert CD first (player.play()的执行结果)
插入了周杰伦的CD… (player.insertCD(&cd)的执行结果)
正在播放周杰伦的CD…
Singer: 周杰伦
- 青花瓷
- 菊花台
- 三节棍
- 东风破
- 珊瑚海
- 稻香
弹出了周杰伦的CD… (player.ejectCD()的执行结果)
源代码如下:
#include<iostream>
#include<string>
using namespace std;
class CD
{
public:
CD(string name, string songs[]);
string getSinger(); //获得歌手的名字
string getSong(int index); //获得某首歌的歌名
void listSongs(); //列出CD的内容
//~CD();
private:
string singer;
string songs[6];
};
CD::CD(string name, string songs[])
{
this->singer = name;
for (int i = 0; i < 6; i++) {
this->songs[i] = songs[i];
}
}
string CD::getSinger() {
return singer;
}
string CD::getSong(int index) {
return songs[index - 1];
}
void CD::listSongs() {
cout << "Singer's Name: " << singer << endl;
cout << " 1." << songs[0] << endl;
cout << " 2." << songs[1] << endl;
cout << " 3." << songs[2] << endl;
cout << " 4." << songs[3] << endl;
cout << " 5." << songs[4] << endl;
cout << " 6." << songs[5] << endl;
}
class CDPlayer
{
public:
CDPlayer();
void showMenu(); //提供用户菜单
void insertCD(CD* cd); //插入CD
CD* ejectCD();
void play();
private:
CD* cd;
bool cdIn;
};
CDPlayer::CDPlayer(){
cd = NULL;
cdIn = false;
}
void CDPlayer::showMenu() {
cout << "***********************************************"<< endl;
cout << "* 1.播放CD *" << endl;
cout << "* 2.插入CD *" << endl;
cout << "* 3.弹出CD *" << endl;
cout << "* 0.关机 *" << endl;
cout << "***********************************************" << endl;
}
void CDPlayer::insertCD(CD* cd) {
if (cdIn)
cout << "CD已经插入了,请先弹出...." << endl;
else {
CDPlayer::cd = cd;
cdIn = true;
cout << "已经插入了" << cd->getSinger() << "的CD....." << endl;
}
}
CD* CDPlayer::ejectCD() {
CD* temp = cd;
if (cdIn) {
cout << "弹出了" << cd->getSinger() << "的CD......" << endl;
cdIn = true;
cd = 0;
return temp;
}
else {
cout << "没有CD,不需弹出....." << endl;
return NULL;
}
}
void CDPlayer::play() {
if (cdIn) {
cout << "正在播放" << cd->getSinger() << "的CD....." << endl;
cd->listSongs();
}
else {
cout << "Please insert CD first......" << endl;
}
}
void main() {
string name;
string songs[6];
cout << "制造CD......" << endl;
//输入歌手名字
cout << "Singer's Name:" << endl;
cin >> name;
for (int i = 0; i < 6; i++) {
cout << "song" << (i + 1) << "#:";
cin >> songs[i];
}
CD cd(name, songs);
cd.listSongs();
CDPlayer player;
player.showMenu();
player.play();
player.insertCD(&cd);
player.play();
player.ejectCD();
}
2.3 编写购物车结算程序
(1)问题描述
顾客在一家大型超市中购买商品(Goods),取下所需数量的商品,放入购物车(Cart)中并到收银台结算。购买时,从货架上取下所需数量的商品,放入购物车中;购买结束后,将商品的信息打印出来,并打印商品的总价。
商品类Goods的数据成员包括:商品名称(name,string类型)、标牌价格(price,double类型)、购买数量(num,double类型)。购物车类Cart的数据成员包括:用于保存购买商品的数组。此外,购物车类提供添加商品、商品结算等服务。要求创建新的工程项目CartManagement。
下面只给出了类定义的主要接口,其他数据成员和函数成员可以自由扩展。
class Goods { // 商品类
public:
void printInfo(); // 输出该商品的信息:名称、标牌价格、购买数量
private:
string name;
double price;
double num;
};
class Cart { // 购物车类
public:
void addItem(…); // 添加一定数量的商品到购物车
double checkout(…); // 对购物车中的商品进行结算
void printInvoice(…); // 将商品信息输出到显示器
private:
Goods iterms[20];
};
int main() {
Goods tShirt(“Tshirt”, 79, 2);// 创建服装对象,名称、价格、数量
Goods suit(“suit”, 1099, 1); // 套装
Goods hat(“hat”, 129, 3); // 帽子
Goods tv(“tv set”, 4899, 1); // 创建家电对象,名称、价格、数量
Goods ac(“air condition”, 5280, 1);// 空调
//将商品添加到购物车
myCart.addItem(tShirt);
myCart.addItem(suit);
myCart.addItem(hat);
myCart.addItem(tv);
myCart.addItem(ac);
myCart.checkout(); // 购物车商品结算,显示顾客需要支付的总金额
myCart.printInvoice(); // 将购物清单输出到显示器上
return 0;
}
(2)问题要求
程序的执行结果如下:
您需要支付11823元。
T shirt,79,2
suit,1099,1
hat,129,3
tv set,4899,1
air condition,5280,1
源代码如下:
#include<iostream>
#include<string>
using namespace std;
class Goods {
public:
Goods(string name="",double price=0 ,double num=0):name(name),price(price),num(num){}
void printInfo();
double getPrice();
double getNum();
private:
string name;
double price;
double num;
};
void Goods::printInfo() {
cout << name << "," << price << "," << num<<endl;
}
double Goods::getPrice() {
return price;
}
double Goods::getNum() {
return num;
}
class Cart {
public:
Cart():count(0){}
void addItem(Goods good);
double checkout();
void printInvoice();
private:
Goods iterms[20];
int count;
};
void Cart::addItem(Goods good) {
iterms[count] = good;
count++;
}
double Cart::checkout() {
double allprice=0;
for (int i = 0; i < count; i++) {
allprice += iterms[i].getPrice() * iterms[i].getNum();
}
cout << "您需要支付" << allprice << "元" << endl;
return allprice;
}
void Cart::printInvoice() {
for (int i = 0; i <count; i++)
iterms[i].printInfo();
}
int main() {
Goods tShirt("Tshirt", 79, 2);
Goods suit("suit", 1099, 1);
Goods hat("hat", 129, 3); // 帽子
Goods tv("tv set", 4899, 1); // 创建家电对象,名称、价格、数量
Goods ac("air condition", 5280, 1);// 空调
Cart myCart;
//将商品添加到购物车
myCart.addItem(tShirt);
myCart.addItem(suit);
myCart.addItem(hat);
myCart.addItem(tv);
myCart.addItem(ac);
myCart.checkout(); // 购物车商品结算,显示顾客需要支付的总金额
myCart.printInvoice();
}