实验51参考答案.docx
《实验51参考答案.docx》由会员分享,可在线阅读,更多相关《实验51参考答案.docx(21页珍藏版)》请在冰点文库上搜索。
实验51参考答案
实验5
(1)类的组合
参考答案
一、实验目的与实验要求
(1)理解类组合的概念与作用。
(2)掌握对象成员的定义方法,理解对象成员的构造与析构方法。
(3)理解组合后类的构造函数与析构函数的调用次序。
(4)掌握对象成员中私有成员和保护成员的访问方法。
二、实验内容
题目1:
对象成员的定义、构造与访问。
定义三个类Member1、Member2和New。
Member2中包含有Member1类型的成员,New中包含有Member1与Member2类型的成员。
程序的具体要求如下。
①在Member1类中,它含有一个int型私有数据成员x以及三个公有成员函数。
三个成员函数分别为构造函数、析构函数与显示函数show()。
show()函数的作用是输出x的值。
②在Member2类中,它含有三个私有数据成员,分别是Member1型的对象obj1、obj2与int型的数据y。
此外,它还含有三个公有成员函数,分别是构造函数、析构函数与显示函数show()。
show()函数的作用是输出y的值。
③在New类中,它含有三个私有数据成员,分别是Member1型的对象m1、Member2型的对象m2与int型的数据z。
此外,它还含有三个公有成员函数,分别是构造函数、析构函数与显示函数show()。
show()函数的作用是输出z的值。
④main()函数中定义一个New型的对象,并调用show()函数。
程序为:
#include
usingnamespacestd;
classMember1
{
public:
Member1(inta)
{
x=a;
cout<<"constructingMember1"<}
~Member1()
{
cout<<"donstructingMember1\n";
}
voidshow()
{
cout<<"Member1x="<}
private:
intx;
};
classMember2
{
public:
Member2(inta,intb,intc):
obj1(a),obj2(b)
{
y=c;
cout<<"constructingMember2"<}
~Member2()
{
cout<<"donstructingMember2\n";
}
voidshow()
{
cout<<"Member2y="<}
private:
Member1obj1,obj2;
inty;
};
classNew
{
public:
New(inta,intb,intc,intd,inte):
m1(a),m2(b,c,d)
{
z=e;
cout<<"constructingNew"<}
~New()
{
cout<<"donstructingNew\n";
}
voidshow()
{
cout<<"Newz="<}
private:
Member1m1;
Member2m2;
intz;
};
intmain()
{
Newex(1,2,3,4,5);
ex.show();
return0;
}
题目2:
类组合的应用。
编写一个程序,对一批学生的资料进行处理。
程序的具体要求如下。
①编写日期类Date,它含有三个私有int型数据成员year、month、day,分别表示年、月、日。
此外,它还含有五个公有成员函数,分别是构造函数、显示函数Show()、取值函数GetYear()、GetMonth()和GetDay()。
Show()的功能是输出当前对象的日期,GetYear()、GetMonth()、GetDay()的作用分别是返回year、month和day的值。
②编写学生类Student,它含有三个私有数据成员,分别是字符串型变量name、int型变量score与Date型变量birthday,分别表示学生的姓名、成绩与出生日期。
此外,它还含有五个公有成员函数,分别是构造函数、显示函数Show()、取值函数GetName()、GetScore()和GetDate()。
Show()的功能是输出当前对象的所有信息,GetName()、GetScore()、GetDate()的作用分别是返回name的首地址、score的值以及birthday的值。
③编写函数CompareDate。
它的原型如下,它的作用是比较日期d1和d2的前后。
如果d1在d2前,返回-1,如果d1在d2后,返回1,如果d1和d2是同一天,返回0。
intCompareDate(Dated1,Dated2);
④编写函数SortByName。
它的原型如下,它的作用是对st数组的前num个数据按姓名进行排序。
voidSortByName(Student*st,intnum);
⑤编写函数SortByScore。
它的原型如下,它的作用是对st数组的前num个数据按成绩进行排序。
voidSortByScore(Student*st,intnum);
⑥编写函数SortByBirthday。
它的原型如下,它的作用是对st数组的前num个数据按出生日期进行排序。
voidSortByBirthday(Student*st,intnum);
⑦编写函数PrintStudent。
它的原型如下,它的作用是输出st数组的前num项。
voidPrintStudent(Student*st,intnum);
⑧编写主函数main(),在main()中定义对象数组st,并调用上述函数进行测试。
st数组使用下列数据进行初始化。
Jack,99,1990,2,5
Mike,62,1989,12,25
Tom,88,1990,3,14
Kate,74,1989,10,15
Rowen,92,1990,5,22
程序如下:
#include
usingnamespacestd;
classDate
{
public:
Date(inty=2000,intm=1,intd=1)
{
year=y;
month=m;
day=d;
}
voidShow()
{
cout<}
intGetYear()
{
returnyear;
}
intGetMonth()
{
returnmonth;
}
intGetDay()
{
returnday;
}
private:
intyear;
intmonth;
intday;
};
classStudent
{
public:
Student(inty=0,intm=0,intd=0,ints=0,char*p=""):
birthday(y,m,d)
{
strcpy(name,p);
score=s;
}
voidShow()
{
cout<birthday.Show();
}
char*GetName()
{
returnname;
}
intGetScore()
{
returnscore;
}
DateGetDate()
{
returnbirthday;
}
private:
charname[20];
intscore;
Datebirthday;
};
intCompareDate(Dated1,Dated2);
voidSortByName(Student*,intnum);
voidSortByScore(Student*,intnum);
voidSortByBirthday(Student*,intnum);
voidPrintStudent(Student*,intnum);
intmain()
{
Studentst[5]={Student(1990,2,5,99,"Jack"),
Student(1989,12,25,62,"Mike"),
Student(1990,3,14,88,"Tom"),
Student(1989,10,15,74,"Kate"),
Student(1990,5,22,92,"Rowen")};
PrintStudent(st,5);
cout<SortByName(st,5);
PrintStudent(st,5);
cout<SortByScore(st,5);
PrintStudent(st,5);
cout<SortByBirthday(st,5);
PrintStudent(st,5);
return0;
}
intCompareDate(Dated1,Dated2)
{//intt;
if(d1.GetYear()return-1;
elseif(d1.GetYear()==d2.GetYear())
if(d1.GetMonth()return-1;
elseif(d1.GetMonth()==d2.GetMonth())
if(d1.GetDay()return-1;
elseif(d1.GetDay()==d2.GetDay())
return0;
elsereturn1;
elsereturn1;
elsereturn1;
}
voidSortByName(Student*st,intnum)
{
Studentt;
intk;
for(inti=0;i{k=i;
for(intj=i+1;j//if(st[k].GetName()>st[j].GetName())
if(strcmp(st[k].GetName(),st[j].GetName())>0)
k=j;
t=st[k];
st[k]=st[i];
st[i]=t;
}
}
voidSortByScore(Student*st,intnum)
{
Studentt;
intk;
for(inti=0;i{k=i;
for(intj=i+1;jif(st[k].GetScore()k=j;
t=st[k];
st[k]=st[i];
st[i]=t;
}
}
voidSortByBirthday(Student*st,intnum)
{
Studentt;
intk;
for(inti=0;i{k=i;
for(intj=i+1;jif(CompareDate(st[k].GetDate(),st[j].GetDate())==1)
k=j;
t=st[k];
st[k]=st[i];
st[i]=t;
}
}
voidPrintStudent(Student*st,intnum)
{for(inti=0;ist[i].Show();
}
运行结果为:
Jack991990-2-5
Mike621989-12-25
Tom881990-3-14
Kate741989-10-15
Rowen921990-5-22
Jack991990-2-5
Kate741989-10-15
Mike621989-12-25
Rowen921990-5-22
Tom881990-3-14
Jack991990-2-5
Rowen921990-5-22
Tom881990-3-14
Kate741989-10-15
Mike621989-12-25
Kate741989-10-15
Mike621989-12-25
Jack991990-2-5
Tom881990-3-14
Rowen921990-5-22
Pressanykeytocontinue
三、实验指导
题目1指导:
①程序的主要代码如下,在横线上补充相应的语句。
#include
usingnamespacestd;
classMember1
{
public:
Member1(inta)
{
x=a;
cout<<"constructingMember1"<}
~Member1()
{
cout<<"donstructingMember1\n";
}
voidshow()
{
cout<<"Member1x="<}
private:
intx;
};
classMember2
{
public:
Member2(
(1)):
(2)
{
y=c;
cout<<"constructingMember2"<}
~Member2()
{
cout<<"donstructingMember2\n";
}
voidshow()
{
cout<<"Member2y="<}
private:
Member1obj1,obj2;
inty;
};
classNew
{
public:
New((3)):
(4)
{
z=e;
cout<<"constructingNew"<}
~New()
{
cout<<"donstructingNew\n";
}
voidshow()
{
cout<<"Newz="<}
private:
Member1m1;
Member2m2;
intz;
};
intmain()
{
Newex((5));
ex.show();
return0;
}
②观察程序的运行结果,分析构造函数与析构函数的调用次序。
答:
运行结果如下:
constructingMember11
constructingMember12
constructingMember13
constructingMember24
constructingNew5
Newz=5
donstructingNew
donstructingMember2
donstructingMember1
donstructingMember1
donstructingMember1
Pressanykeytocontinue
构造函数的调用次序是:
首先调用对象成员的构造函数,多个对象成员时按定义顺序执行其对应的构造函数;然后调用对象自身的构造函数。
析构时其调用顺序与构造函数顺序相反。
Newex(1,2,3,4,5);时,构造函数的调用调用顺序为:
m1的构造函数Member11
m2的构造函数,首先调用obj1的构造函数Member11,然后调用obj2的构造函数Member1,最后调用m2自己的构造函数Member2
调用ex自身的构造函数New
析构函数调用的过程相反。
③改变Member2构造函数初始化表中各项的次序,并再次运行程序,观察结果并分析构造函数与析构函数的调用次序。
答:
因为构造函数的调用与初始化表中各项的次序无关,如果参数对应的对象成员不变,结果也不变。
④在Member2构造函数中添加语句obj1.x=50是否可行?
分析其原因。
答:
不可行。
原因:
输出窗口区显示:
errorC2248:
'x':
cannotaccessprivatememberdeclaredinclass'Member1'
因为x在Member1中是私有成员,在Member2类中不能直接访问Member1中的私有成员。
⑤在main()中添加下列语句是否可行?
分析其原因。
ex.m1.show();
ex.m2.show();
答:
不可行。
原因:
输出窗口显示:
'm1':
cannotaccessprivatememberdeclaredinclass'New'
'm2':
cannotaccessprivatememberdeclaredinclass'New'
m1,m2在New类中属于私有的对象成员,在类外的main函数中不可直接访问。
⑥在Member2与New中的show()函数添加语句,使得main()中ex.show();能输出所有x、y和z的值。
答:
Member2中的show()函数修改为如下:
voidshow()
{
cout<<"obj1.";
obj1.show();
cout<<"obj2.";
obj2.show();
cout<<"Member2y="<}
New中的show()函数修改为如下:
voidshow()
{
cout<<"m1.";m1.show();
cout<<"m2."<cout<<"Newz="<}
运行结果为:
constructingMember11
constructingMember12
constructingMember13
constructingMember24
constructingNew5
m1.Member1x=1
m2.
obj1.Member1x=2
obj2.Member1x=3
Member2y=4
Newz=5
donstructingNew
donstructingMember2
donstructingMember1
donstructingMember1
donstructingMember1
Pressanykeytocontinue
题目2指导:
①Date类、Student类与main()的主要代码如下,在横线上补充相应的语句。
classDate
{
public:
Date(inty=2000,intm=1,intd=1)
{
year=y;
month=m;
day=d;
}
voidShow()
{
cout<}
intGetYear()
{
returnyear;
}
intGetMonth()
{
returnmonth;
}
intGetDay()
{
returnday;
}
private:
intyear;
intmonth;
intday;
};
classStudent
{
public:
Student(
(1)):
(2)
{
strcpy(name,p);
score=s;
}
voidShow()
{
cout<(3);
}
char*GetName()
{
returnname;
}
intGetScore()
{
returnscore;
}
DateGetDate()
{
return(4);
}
private:
charname[20];
intscore;
Datebirthday;
};
intmain()
{
Studentst[5]={(5)};
PrintStudent((6));
SortByName((7));
PrintStudent((8));
SortByScore((9));
PrintStudent((10));
SortByBirthday((11));
PrintStudent((12));
return0;
}
②声明、实现下列函数,并运行程序进行测试。
intCompareDate(Dated1,Dated2);
voidSortB