实验六__继承三_——_多继承及继承的应用

更新时间:2023-08-26 14:43:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

电脑知识文档

实验六继承㈢——多继承及继承的应用

一、实验目的

1.理解多继承的概念,熟悉多继承的定义及应用;

2.理解多继承方式下的二义性产生原因,熟悉解决二义性的方法;

3.进一步熟悉继承的综合应用。

二、实验学时

课内实验:2课时课外练习:2课时

三本实验涉及的新知识

㈠多继承的概念

如果一个派生类由二个或二个以上的基类派生得到,称为多重继承(多继承)㈡多继承派生类的定义

格式:

class派生类名:继承方式1,基类名1,继承方式2,基类名2,…

{派生类新定义的成员}

㈢多继承派生类的构造函数

1.定义

格式:

构造函数名(总参数表):基类名1(参数表1),基类名2(参数表2),…

{构造函数的函数体}

2.说明

⑴多继承的构造函数的总参数表必须提供所有基类构造函数的值及新增数据成员的值。

⑵定义派生类对象时,多继承方式下构造函数的执行顺序为:先执行所有基类的构造函数(按排列顺序)后执行派生类的构造函数。

⑶释放派生类对象时,析构函数的执行顺序与构造函数的执行顺序相反。

㈣多继承派生类中为数据成员提供值的函数

在多继承方式下,为数据成员提供值的函数必须同时为所有基类的数据成员提供值。㈤多继承的二义性

1.同名函数产生的二义性

在多重继承方式下,如果在多个基类中有同名成员函数,可能出现二义性问题。解决办法是在调用函数时使用类名及作用域运算符。

2.间接基类产生的二义性

在多重继承下,如果一个派生类由二个或以上基类派生得到,而这些基类又是由一个基类派生得到的,也会产生二义性。解决办法是使用虚基类,即在定义直接基类时,将间接基类说明为虚基类。

定义格式:

class直接基类名:virtual继承方式间接基类名

{派生类新定义的成员}

电脑知识文档

四、实验内容

㈠验证及认知实验

按要求调试下列程序,并回答相关问题。

程序1(exp_601.cpp)

#include<iostream.h>

classX

{intx;

public:

X(inta=0){x=a;}//基类X的构造函数

voidset_x(inta){x=a;}

voidshow(void)

{cout<<"x="<<x;}

};

classY

{inty;

public:

Y(intb=0){y=b;}//基类Y的构造函数

voidset_y(intb){y=b;}

voidshow(void)

{cout<<"y="<<y;}

};

classZ:publicX,publicY

//classZ:publicX,privateY

{intz;

public:

Z(inta=0,intb=0,intc=0):X(a),Y(b)

{z=c;}//派生类Z的构造函数

voidset_xyz(inta,intb,intc)

{set_x(a);set_y(b);z=c;}

voidshow_z(void)

{cout<<"z="<<z;}

voidprint(void)

{show();//显示x的值

show();//显示y的值

show_z();//显示z的值

}

};

voidmain()

{Zobj1(3,4,5),obj2;

obj2.set_xyz(10,20,30);

obj1.print();cout<<endl;

obj2.print();cout<<endl;

}

问题:

电脑知识文档

⑴编译该程序,会出现编译错误,其原因是在定义Z类的print()成员函数中的show()函数调用时出现了

⑵将“show();

⑶将“show();。解决的方法是://显示x的值”中的“show()”改为//显示y的值”中的“show()”改为

⑷调试成功后的输出结果是:

是成员函数voidset_xyz(inta,intb,intc)中“set_x(a)”的作用,“set_y(b)”的作用是。

程序2(exp_602.cpp)

#include<iostream.h>

classbase

{private:

inta;

public:

base(intx)

{a=x;

cout<<"Constructingbasea="<<a<<endl;

}

};

classbase1:publicbase

{private:

intb;

public:

base1(intx1,intx2):base(x1)

{b=x2;

cout<<"Constructingbase1b="<<b<<endl;

}

};

classbase2:publicbase

{private:

intc;

public:

base2(intx1,intx2):base(x1)

{c=x2;

cout<<"Constructingbase2c="<<c<<endl;

}

};

classderived:publicbase1,publicbase2

{private:

intd;

public:

电脑知识文档

derived(intx1,intx2,intx3,intx4):base1(x1,x2),base2(x1,x3)

{d=x4;

cout<<"Constructingderivedd="<<d<<endl;

}

};

voidmain(void)

{derivedobj(2,3,4,5);}

问题:

⑹编译运行程序的输出结果是:

⑺从输出结果中可看出,间接基类“base”被调用了两次,产生原因是“derived”的两个直接基类“base1”、“base2”拥有共同基类“base”,产生了。

⑻将程序中“classbase1:publicbase”改为“classbase1:virtualpublicbase”

“classbase2:publicbase”改为“classbase2:virtualpublicbase”

“derived(intx1,intx2,intx3,intx4):base1(x1,x2),base2(x1,x3)”改为

“derived(intx1,intx2,intx3,intx4):base(x1),base1(x1,x2),base2(x1,x3)”重新编译运行程序的输出结果是:

⑼“virtualpublicbase”表示间接基类“base”为

㈡知识应用实验。

按要求调试程序(完善类的定义及主程序)。

1.题目:通过继承方式处理学生成绩。

2.内容

⑴类的定义:

人“person”类(person.h中定义):包括姓名、性别、出生日期(日期“date”本身是一个类,包括年、月、日三个成员——定义在date.h中)三个数据成员;

学生“student”类(student.h中定义),公有继承person类,新增学号、系、进校时间(date对象)三个数据成员;

成绩score类(score.h中定义):新增课程科数、成绩数组数据成员。

⑵成绩处理:源程序存放在“exp_603.cpp”中。

3.要求

⑴完善类的定义;

⑵程序调试办法:每建好一个类,均在main()函数中进行测试成功后再定义下一个类,测试程序以“exp_test.cpp”存盘;

电脑知识文档

⑶所有类定义测试后再调试、完善成绩处理程序。

程序:

//测试程序exp_test.cpp

#include<iostream.h>

#include<iomanip.h>

#include""//用不同类头文件

voidmain()

{……}

//各个类的定义

//date类的定义:存放在date.h中

classdate

{private:

intyear,month,day;//年、月、日三个私有成员

public:

date(void)

{year=1980;month=1;day=1;}

voidset_date(inty,intm,intd)

{}//完成成员函数的定义

intget_year(void)

{}//完成成员函数的定义

intget_month(void)

{}//完成成员函数的定义

intget_day(void)

{}//完成成员函数的定义

};

//person类的定义:保存在person.h中

#include<string.h>

#include"date.h"

classperson

{protected:

charname[11];

charsex[2];

datebirthday;

public:

person(void);//无参构造函数

voidset_person(char*na,char*s,inty,intm,intd);

char*get_name(void)

{}//完成成员函数的定义

char*get_sex(void)

{}//完成成员函数的定义

intget_year(void)

{}//完成成员函数的定义

intget_month(void)

{returnbirthday.get_month();}

电脑知识文档

{}

voidprint(void);//完成成员函数的定义

};

person::person(void)//无参构造函数

{strcpy(name,"无名氏");

strcpy(sex,"男");

birthday.set_date(1980,1,1);

}

voidperson::set_person(char*na,char*s,inty,intm,intd)

{}//完成成员函数的定义

voidperson::print(void)

{cout<<"姓名:"<<name<<endl;

cout<<"性别:"<<sex<<endl;

cout<<"出生日期:"<<birthday.get_year()<<"年";

cout<<birthday.get_month()<<"月";

cout<<birthday.get_day()<<"日"<<endl;

}

//student类的定义:存放在student.h中

#include"person.h"

classstudent:publicperson

{public:

intid;

chardepartment[20];

dateenterdate;

public:

student(void);

voidset_student(intn,char*s,inty,intm,intd);

intget_id(void)

{}//完成成员函数的定义

char*get_department(void)

{}//完成成员函数的定义

intget_enteryear(void)

{}//完成成员函数的定义

intget_entermonth(void)

{}//完成成员函数的定义

intget_enterday(void)

{}//完成成员函数的定义

voidprint(void);

voidprint_base();

};

student::student(void)

{strcpy(name,"无名氏");

strcpy(sex,"男");

birthday.set_date(1980,1,1);

电脑知识文档

id=0;

strcpy(department,"计算机");

enterdate.set_date(2000,9,1);

}

voidstudent::set_student(intn,char*s,inty,intm,intd)

//n、s、y、m、d分别为id、department、enterdate提供值

{}//完成成员函数的定义

voidstudent::print(void)

{cout<<"学号:"<<id<<endl;

person::print();

cout<<"系(专业):"<<department<<endl;

cout<<"进校日期:"<<enterdate.get_year()<<"年";

cout<<enterdate.get_month()<<"月";

cout<<enterdate.get_day()<<"日"<<endl;

}

voidstudent::print_base()

{cout<<setw(8)<<get_id();

cout<<setw(12)<<get_name();

cout<<setw(4)<<get_sex();

cout<<setw(6)<<get_year()<<"-"<<get_month()<<"-"<<get_day();

cout<<setw(20)<<get_department();

cout<<setw(6)<<get_enteryear()<<"-"<<get_entermonth();

cout<<"-"<<get_enterday()<<endl;

}

//score类的定义:存放在score.h中

#include"student.h"

constintM=10;

classscore:publicstudent

{private:

floatsc[M],aver;

intm;

public:

score(void);//无参构造函数

voidset_score(floatx[],intn);//提供成绩

floatget_score(inti)//得到第i科成绩

{}//完成成员函数的定义

floatget_aver(void)//得到平均成绩

{}//完成成员函数的定义

voidprint(void);

voidprint_score(void);

};

score::score(void)//无参构造函数

{

strcpy(name,"无名氏");

电脑知识文档

strcpy(sex,"男");

birthday.set_date(1980,1,1);

id=0;

strcpy(department,"计算机");

enterdate.set_date(2000,9,1);

inti;

m=M;

for(i=0;i<m;i++)

sc[i]=0;

aver=0;

}

voidscore::set_score(floatx[],intn)//提供成绩:完成成员函数的定义

{inti;floatsum=0;

m=n;

for(i=0;i<m;i++)

{}

aver=sum/m;

}

voidscore::print(void)//重载输出print()

{student::print();

inti;

for(i=0;i<m;i++)

cout<<""<<sc[i];

cout<<""<<aver<<endl;

}

voidscore::print_score(void)

{intj;

cout<<setw(8)<<get_id();

cout<<setw(12)<<get_name();

for(j=0;j<m;j++)

cout<<setw(6)<<get_score(j);

cout<<""<<setw(6)<<get_aver()<<endl;

}

//成绩处理程序:保存在exp_603.cpp中

#include<iostream.h>

#include<iomanip.h>

#include"score.h"

voidinput_base(score*p,intn);//学生基本数据输入

voidinput_score(score*p,intn,intm);//学生成绩输入

voidprint_base(score*p,intn);//学生基本数据输出

voidprint_score(score*p,intn,intm);//学生成绩输出

score&average(score*p,intn,intm);//普通函数:平均成绩计算

voidsort(score*p,intn,intm);//普通函数:按平均成绩排序

voidmain()

{intn,m;

电脑知识文档

cout<<"学生人数:";cin>>n;

cout<<"考试科数:";cin>>m;

score*p,aver;

p=newscore[n];//动态分配内存单元——动态数组

if(p==NULL)

{cout<<"内存分配失败"<<endl;

return;

}<文档由小强收集,如果喜欢电

影可以关注pplive网络电视官方下载http://www.77cn.com.cn/

intch;

do

{

cout<<"\n\n请选择:\n";

cout<<"1.输入学生基本数据\n";

cout<<"2.输入学生成绩\n";

cout<<"3.计算课程平均成绩\n";

cout<<"4.输出学生基本数据\n";

cout<<"5.输出学生成绩\n";

cout<<"6.按平均成绩排序\n";

cout<<"0.退出\n";

cout<<"\n输入你的选择:";

cin>>ch;

switch(ch)

{case1:input_base(p,n);break;

case2:input_score(p,n,m);break;

case3:aver=average(p,n,m);break;

case4:print_base(p,n);break;

case5:print_score(p,n,m);aver.print_score();break;

case6:sort(p,n,m);break;

case0:break;

}

}

while(ch);

delete[]p;//释放内存

}

voidinput_base(score*p,intn)//学生基本数据输入

{inti,id,y1,m1,d1,y2,m2,d2;

charname[11],sex[3],dpt[20];

cout<<"\n请输入学生基本数据:";

for(i=0;i<n;i++)

{cout<<"第"<<i+1<<"个学生:\n";

cout<<"学号:";cin>>id;

cout<<"姓名:";cin>>name;

cout<<"性别:";cin>>sex;

cout<<"出生年:";cin>>y1;

cout<<"出生月:";cin>>m1;

电脑知识文档

cout<<"出生日:";cin>>d1;

cout<<"所在系:";cin>>dpt;

cout<<"入学年:";cin>>y2;

cout<<"入学月:";cin>>m2;

cout<<"入学日:";cin>>d2;

p[i].set_person();//完成函数的调用

p[i].set_student();//完成函数的调用

}

}

voidinput_score(score*p,intn,intm)

{inti,j;floatx[M];

for(i=0;i<n;i++)

{cout<<p[i].get_id()<<p[i].get_name()<<"的成绩:"<<endl;

for(j=0;j<m;j++)

{cout<<"第"<<j+1<<"科成绩:";

cin>>x[j];

}

p[i].set_score();//完成函数的调用

}

}

voidprint_base(score*p,intn)

{inti;

for(i=0;i<n;i++)

p[i].print_base();

cout<<endl;

}

voidprint_score(score*p,intn,intm)

{inti;

for(i=0;i<n;i++)

p[i].print_score();

}

score&average(score*p,intn,intm)//用返回引用的方法

{inti,j;floats[M]={0};

staticscoreaver;//返回的对象必须是静态的

for(j=0;j<m;j++)

{for(i=0;i<n;i++)

s[j]=s[j]+p[i].get_score(j);

s[j]=s[j]/n;

}

aver.set_person("平均成绩","",0,0,0);

aver.set_score();//完成函数的调用

returnaver;

}

voidsort(score*p,intn,intm)//选择法排序:完成空白处的内容

{scoret;floata;

inti,j,k;

电脑知识文档

for(i=0;i<n-1;i++)

{a=p[i].get_aver();k=i;

for(j=i+1;j<n;j++)

if()

{a=p[j].get_aver();k=j;}

if()

{t=p[i];p[i]=p[k];p[k]=t;}

}

}

㈢程序设计实验

编程对日期时间型数据进行处理。要求:

1、定义日期型“Date”类,保存在“date.h”中(成员函数包括日期赋初值,设置日期,读取年、月、日,显示年、月、日及判断是否闰年等)。

2、定义时间型“Time”类,保存在“Time.h”中(与实验一中的类相同)。

3、定义日期时间型“DateTime”类保存在“datetime.h”中:

⑴公有继承Date类及Time类;

⑵不增加数据成员;

⑶增加日期时间处理成员函数,包括初始化日期时间、设置日期时间、显示日期时间等。

4、编写main()函数保存在“exp_603.cpp”中,内容自定。

五、实验收获与创新

1.自己拟定一个解决实际问题的题目,综合应用实验一至实验六的知识编程实现。

2.通过实验四、实验五、实验六,谈谈你对面向对象程序设计继承的认识。

本文来源:https://www.bwwdw.com/article/dl1i.html

Top