c++实验报告8.docx
- 文档编号:2362431
- 上传时间:2022-10-29
- 格式:DOCX
- 页数:36
- 大小:384.48KB
c++实验报告8.docx
《c++实验报告8.docx》由会员分享,可在线阅读,更多相关《c++实验报告8.docx(36页珍藏版)》请在冰豆网上搜索。
c++实验报告8
评语:
评分项目
评分内容
分值
评分结果
预习情况
是否完成预习工作。
要求按实验指导书进行预习、并完成实验报告初稿、编写程序。
20
实验方案
实验方案是否可行。
要求目的、任务明确、原理清楚、步骤可操作、对实验过程数据有记录方案、对可能的错误有预备方案。
30
实验过程
与结果
实验结果是否正确。
要求完成实验过程中的数据记录、记录要完整和准确、内容要详细,实验结果要与预期的正确结果一致。
35
实验结论
实验结论是否正确。
要求根据实验原理对实验过程中的数据、实验结果进行分析,得出实验结论。
15
总分
100
指导教师(签名)
年月日
说明:
指导教师评分后,实验报告交院(系)办公室保存。
实验8继承
一.实习目的及要求
1)掌握继承的实现方法;
2)继承中常见问题的处理方法。
二.预习
预习派生类的定义和使用、创建派生类对象时构造函数的调用次序、多重继承中的冲突、及虚基类。
预习笔记总结:
派
生
类
定
义
Class派生类名:
继承方式基类名1,继承方式基类名2,…{};
使
用
吸收基类成员
包含基类除构造和析构函数之外的所有成员
改造基类成员
新成员与基类成员同名则派生类(或其对象)只能访问派生类中同名的成员
添加基类成员
需要在派生类中加入新的构造和析构函数
继承方式
基类
公有成员
保护成员
私有成员
公有继承
公有成员
保护成员
无论是派生类成员还是派生类对象都无法直接访问基类的私有成员
私有继承
私有成员
私有成员
保护继承
保护成员
保护成员
类型兼容规则
在需要基类对象的任何地方,都可使用公有派生类的对象来替代。
在替代之后,派生类对象就可以作为基类的对象使用,但只能使用从基类继承的成员。
派生类的对象可以赋值给基类的对象;可以初始化基类的引用
派生类对象的地址可以赋给指向基类的指针。
派生类构造函数
语法
派生类名:
:
派生类名(参数表):
基类名1(参数表1),…,基类名n(参数表n),内嵌对象名1(内嵌对象参数表1),…内嵌对象名m(内嵌对象参数表m){}
执行次序
调用基类构造函数,调用顺序按照它们被声明的的顺序(从左向右)
调用内嵌成员对象的构造函数,调用顺序按它们在类中声明的顺序
派生类的构造函数体中的内容
如果基类声明了带有形参表的构造函数时,派生类应当声明构造函数,提供一个将参数传递给基类构造函数的途径,保证在基类惊醒初始化时能获得必要的数据。
多重继承
冲突
多继承同名隐藏:
派生类成员隐藏所有基类的同名成员
作用域
分辨符
如果访问被隐藏的成员,可以使用作用域分辨符和基类名来限定(基类名:
:
成员名),且必须使用直接基类来限定
虚函数
从不同路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射
三.实验内容
3.1分析下面的程序,指出程序运行的结果
1)分析下面的程序,指出程序运行的结果:
#include
classCBase
{
public:
voidfn1();
};
voidCBase:
:
fn1()
{cout<<"调用基类类的函数fn1()\n";
}
classCDerived:
publicCBase{
public:
voidfn1();
};
voidCDerived:
:
fn1()
{cout<<"调用派生类的函数fn1()\n";
}
voidmain()
{
CDerivedd1;//派生类对象
CBase*pb=&d1;//派生类对象的地
//址赋给指向基类的指针
CBase&pd=d1;//派生类的对象初始//化基类的引用
d1.fn1();
pb->fn1();
pd.fn1();
程序分析:
a)类分析:
此程序有两个类:
基类CBase和派生类CDerived。
类CDerived公有继承类CBase。
类的派生关系的UML图形和对象图表示如下:
b)main部分分析:
根据类型兼容原则,在替代之后,派生类对象就可以作为基类的对象使用,但只能使用从基类继承的成员。
派生类对象d1的地址赋给指向基类的指针pb,通过这个基类类型的指针只能访问从基类CBase继承的fn1(),也就是说虽然pb指向派生类CDerived的对象d1,fn1函数运行时通过这个指针pb这能访问CDerived从CBase继承过来的fn1(),而不是CDerived类中自己的同名成员函数。
同理,派生类的对象初始化基类的引用也是类型兼容替代的一种,通过pd.fn1();访问CDerived从CBase继承过来的fn1(),而不是CDerived类中自己的同名成员函数。
c)结合上述分析,结果预测:
调用派生类的函数fn1()
调用基类类的函数fn1()
调用基类类的函数fn1()
d)调试运行如下,和结果预测分析一致
2)分析下面的程序,指出程序运行的结果:
#include
classCBase1
{
intx;
public:
CBase1()
{x=0;cout<<"调用构造函数CBase1()!
\n";}
CBase1(inta)
{x=1;cout<<"调用构造函数CBase1(int)!
\n";}
~CBase1(){cout<<"调用析构函数~CBase1()!
\n";}
};
classCBase2
{
inty;
public:
CBase2()
{y=0;cout<<"调用构造函数CBase2()!
\n";}
CBase2(inta)
{y=a;cout<<"调用构造函数CBase2(int)!
\n";}
~CBase2(){cout<<"调用析造函数~CBase2()!
\n";}
};
classA
{intx;
public:
A(){x=0;cout<<"调用构造函数A()!
\n";}
A(inta){x=a;cout<<"调用构造函数A(int)!
\n";}
~A(){cout<<"调用析构函数~A()!
\n";}
};
classCDerived:
publicCBase1,virtualpublicCBase2
{
Aa;
public:
CDerived()
{cout<<"调用构造函数CDerived()!
\n";}
CDerived(intx,inty,intz):
a(x),CBase1(y),CBase2(z)
{cout<<"调用构造函数CDerived(int,int)!
\n";}
~CDerived(){cout<<"调用析造函数~CDerived()!
\n";}
};
voidmain()
{
CDerived*x=newCDerived;
CDerivedy(2,3,4);
deletex;
cout<<"main()函数结束!
\n";
}
程序分析:
a)类分析:
本程序有三个类,其中类CDerived公有继承类CBase1和虚基类CBase2,类CDerived使用类A。
类图和对象图如下:
b)main部分分析:
首先,创建CDerived类指针对象指向CDerived类型数据的内存的首地址,同时按次序调用基类和内嵌对象成员的无参数构造函数初始化。
建立CDerived类对象y并通过构造函数CDerived(intx,inty,intz):
a(x),CBase1(y),CBase2(z)初始化基类和内嵌对象成员,参数表给出了基类及内嵌成员对象所需的全部参数:
根据构造函数调用次序,先调用虚基类CBase1的有参数构造函数,接着调用基类CBase2的有参数构造函数,再调用内嵌对象a的有参数构造函数。
在用delete清理对象x:
按构造函数相反的次序执行派生类析构函数体、调用派生类对象成员所在类的析构函数和调用基类析构函数。
最后自动按同样的次序清理对象y。
c)根据上述分析结果预测:
调用构造函数CBase1()!
调用构造函数CBase2()!
调用构造函数A()!
调用构造函数CDerived()!
调用构造函数CBase1(int)!
调用构造函数CBase2(int)!
调用构造函数A(int)!
调用构造函数CDerived(int,int)!
调用析造函数~CDerived()!
\
调用析构函数~A()!
调用析造函数~CBase2()!
调用析构函数~CBase1()!
main()函数结束!
调用析造函数~CDerived()!
\
调用析构函数~A()!
调用析造函数~CBase2()!
调用析构函数~CBase1()!
d)程序运行与结果演示,发现和预测的不一致:
e)错误分析:
对比结果演示和结果预测发现不同点在于类CBase1和类CBase2的构造和析构函数执行的次序问题。
调用基类构造函数,调用顺序按照它们被声明的的顺序(从左向右),但是基类CBase1在左,虚基类CBase2在右,它们构造函数调用次序从右到左了!
虚基类构造函数调用顺序优先于一般基类。
3.2编写并调试程序:
1).定义一个图形类,其中有保护类型的成员数据:
高度和宽度,一个公有的构造函数。
由该图形类建立两个派生类:
矩形类和等腰三角形类。
在每个派生类中都包含一个函数Area(),分别用来计算矩形和等腰三角形的面积。
a)编程实践方案:
分析
对象分析:
有几个对象,对象之间有什么关系
类分析:
确定类(是否有必要存在)、类名、类的成员和类间关系
设计
根据分析设计图形类、三角形类、矩形类和main的代码
代码测试
在VisualC++平台编译,调试。
如有语法错误,双击调试窗口错误的地方,纠正错误并作错误分析。
如有逻辑错误,重新审核代码设计是否符合要求。
结果预测
长10宽20的矩形的面积为200;长15宽10(底)的三角形的面积为75;长7.8宽8.9的矩形面积为68.42,三角形为34.71
实现
记录测试数据结果和最后的正确代码
b)对象分析
有两类对象:
矩形和等腰三角形。
矩形具有高度、宽度等静态属性,它的面积=高度*宽度;等腰三角形也具有高度、宽度(底)等静态属性,面积=高度*宽度/2。
它们共同的数据属性高度hight和宽度width,不同的面积操作,即动态属性。
所以,两个对象都是图形,但是它们的面积求法不同。
设置两个具体的对象长10宽20的矩形S和长15宽10(底)的三角形T。
c)类分析和设计
根据对象分析,可以抽象出图形类,类名为graph,它包括float类型的hight和width的保护类型数据成员和对数据初始化的构造函数。
同时图形是可被计算面积,因此根据面积求法不同派生出矩形类square和三角形类triangle,它们继承了图形类graph的hight和width数据成员,同时还添加Area()函数实现求面积的功能。
类设计代码如下:
classgraph{
protected:
floathight,width;
public:
graph(floata,floatb){hight=a;width=b;}
};
classtriangle:
publicgraph{
public:
triangle(float
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- c+ 实验 报告