实验五:运行时多态性.doc_第1页
实验五:运行时多态性.doc_第2页
实验五:运行时多态性.doc_第3页
实验五:运行时多态性.doc_第4页
实验五:运行时多态性.doc_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验五:运行时多态性一、基本练习填空1在一个派生类中重新定义基类的虚函数是_ _的另一种特殊形式,在派生类中重新定义此虚函数时,要求_ 、 、 、 和 都必须与基类中原型完全相同。2动态多态性是在程序运行时通过改变具有虚函数定义的基类 使其指向不同派生类 从而调用不同版本的 动态地实现对同一 的不同响应。3阅读以下程序后填空#include class basepublic:virtual void who() coutbase classendl; ;class derived1:public basepublic:void who() coutderived1 classendl; ;class derived2:public basepublic:void who() coutderived2 classwho();p=&obj2; p-who();p=&obj3; p-who(); 其运行结果: 4阅读以下程序后填空#include class basepublic:virtual void f1() coutf1 function of baseendl; virtual void f2() coutf2 function of baseendl; virtual void f3() coutf3 function of baseendl; void f4() coutf4 function of baseendl; ;class derive:public basepublic:void f1() coutf1 function of deriveendl; void f2() coutf2 function of deriveendl; void f4() coutf4 function of derivef1(); p-f2(); p-f3();p=&obj2;p-f1(); p-f2(); p-f4(); 其运行结果: 5阅读以下程序后填空#include class base1public:virtual void f1() coutf1 function of base1endl; void f2() coutf2 function of base1endl; void f3() coutf3 function of base1endl; ;class base2public:void f1() coutf1 function of base2endl; virtual void f2() coutf2 function of base2endl; void f3() coutf3 function of base2endl; ;class derive:public base1,public base2public:void f1() coutf1 function of deriveendl; void f2() coutf2 function of deriveendl; void f3() coutf3 function of derivef1(); p1-f2(); p1-f3();p1=&obj2;p1-f1(); p1-f2(); p1-f3();p2=&obj2;p2-f1(); p2-f2(); p2-f3(); 其运行结果: f1 function of base1 6阅读以下程序后填空#include class basepublic:virtual void f1()=0;virtual void f2()=0;virtual void f3()=0;void f4() coutf4 function of baseendl; ;class derive:public basepublic:void f1() coutf1 function of deriveendl; void f2() coutf2 function of deriveendl; void f3() coutf3 function of deriveendl; void f4() coutf4 function of derivef1(); p-f2(); p-f3(); p-f4(); 其运行结果: 7阅读以下程序后填空#include #include class basepublic:virtual void show()=0;virtual base() coutbase:base()endl; ;class derive:public basechar *buf;public:derive(char *s) buf=new charstrlen(s)+1; strcpy(buf,s); void show() coutbufendl; virtual derive() delete buf; coutderive:derive()show();fun(p); 其运行结果: 8. 阅读以下程序后填空#include class Apublic:virtual A() cout调用A:A()endl; ;class B:public Achar *buf;public:B(int i) buf=new chari; virtual B() delete buf;cout调用B:B()endl; ;void fun(A *a) delete a; void main()A *a=new B(10);fun(a);程序的执行结果: 选择1. 虚函数是用来 ,调用不同版本虚函数用以实现动态多态性 。A. 避免在多继承的多条派生路径中存在共同基类而产生的多个基类副本B. 表现基类和公有派生类的成员函数之间的一种关系的C. 表现基类和派生类的成员函数之间的一种关系的D. 只能通过基类指针指向不同的派生类对象实现E. 只能通过基类指针指向不同的公有派生类对象实现F. 可以通过基类指针指向不同公有的派生类对象或派生类对象本身实现2. 下列关于动态联编的描述中, 是错误的。A. 动态联编是以虚函数为基础的B. 动态联编是在运行时确定所调用的函数代码的C. 动态联编调用函数操作是指向对象的指针或对象引用D. 动态联编是在编译时确定操作函数的3. 下列关于虚函数的描述中, 是正确的。A. 虚函数是一个static类型的成员函数B. 虚函数是一个非成员函数C. 基类中说明了虚函数后,派生类中与其对应的函数可不必说明为虚函数D. 派生类的虚函数与基类的虚函数具有不同的参数个数和类型4. 下列关于纯虚函数和抽象类的描述中, 是错误的。A. 纯虚函数是一种特殊的虚函数,它没有具体的实现B. 抽象类是指具有纯虚函数的类C. 一个基类中说明有纯虚函数,该基类的派生类一定不再是抽象类D. 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出5. 下列描述中, 是抽象类的特性。A. 可以说明虚函数B. 可以进行构造函数重载C. 可以定义友元函数D. 不能说明其对象6. 是一个在基类中说明的虚函数,它在该基类中没有定义,但要求任何派生类都必须定义自己的版本。A. 虚析构函数B. 虚构造函数C. 纯虚函数D. 静态成员函数7. 如果一个类至少有一个纯虚函数,那么就称该类为 。A. 抽象类B. 虚基类C. 派生类D. 以上都不对8 以下保留字( )不能出现在说明虚函数原型的语句中。Astatic B. operator C. void D. const .9以下关于虚函数和纯虚函数的说法中,( )是不正确的A在派生类中虚函数可以不用关键字virtual说明。B. 虚函数在派生类中可以不重定义。C. 不能为虚函数定义缺省操作。D. 纯虚函数在派生类中可以不重定义。10以下关于动态绑定的说法中,正确的是( )A虚基类是动态绑定的。B. 指针是动态绑定的。C. 所有的虚函数和纯虚函数都是动态绑定的。D. 动态绑定与编译系统无关。11以下关于抽象类的说法中,( )是不正确的A不可创建抽象类的实例。B. 可以声明抽象类的引用。C. 抽象类的派生类也是抽象类。D. 抽象类的派生类也可以是抽象类。12以下关于抽象类的说法中,只有( )是正确的A定义抽象类的目的是软件重用。B. 定义抽象类是为了提高访问效率。C. 定义抽象类是使指针的使用更灵活。D. 抽象类提供了对类进行分类的机制。13以下关于多态性的说法中,( )是不正确的A每个多态类的对象有一个虚表指针。B. 虚函数调用与this指针无关。C. 每个多态类的基类都有一个虚函数表。D. 多态类的每一个派生类都有一个虚函数表。14判断下列说法的正误,并解释为什么: (1) 虚函数不能是类的静态成员。 (2) 重定义虚函数的派生类必须是公有继承的。 (3) 对于从基类继承的虚函数,派生类也可以不进行重定义。 (4) 纯虚函数与函数体为空的虚函数等价。 (5) 多态类提供了一种动态多分支派送机制。 (6) 作为虚函数隐含参数的this指针,决定了虚函数调用时执行的代码。15分析下面程序的输出结果:#includeclass Aprotected:int value;public:A(int a)value=a;A()value=1;virtual void show()coutAs value is: valueendl;class B: public Aprotected:int value;public:B(int a):A(a)value=2*a;B()value=2;virtual void show()coutBs value is: A:value,valueendl;class C: public Bpublic:C(int a)value=3*a;virtual void show()coutCs value is: ;coutvalue,A:value,B:valueshow();void main()A obj1(10);B obj2(12);C obj3(25);display(&obj1);display(&obj2);display(&obj3);程序输出:请完成:1下面是一个终端硬件设备驱动程序库的抽象接口定义,试说明利用此接口为该库添加一种智能鼠标的驱动程序的方法和步聚。class Devicepublic:Device(); Device();virtual int open( char*, int, int )=0;virtual int close( int )=0;virtual int read( int, char*, unsigned )=0;virtual int write( int, char*, unsigned )=0;virtual int io_control( int, int )=0;2下面是一个复数抽象类与其直角坐标表示法的实现类。请为它再定义一个极坐标表示法的实现类,并编一段程序对它们进行测试。 #include#include#includeclass Complexpublic:virtual double getReal()=0; /get the real partvirtual double getImage()=0; / get the image partvirtual double getMagnitude()=0; / get the magnitudevirtual double getAngle()=0; / get the angle;void showComplex(Complex& c) coutsetw(14)c.getReal(),setw(14)c.getImage(),;coutsetw(14)c.getMagnitude(),setw(14)c.getAngle()endl;class ComplexRI: public Complex double real, image;public:ComplexRI(double R, double I)real =R;image =I;double getReal() return real; double getImage() return image; double getMagnitude() return sqrt(real*real+image*image); double getAngle() return atan(image/real);测试函数:void main()ComplexRI c1(3, 4),c2(1, -1);ComplexMA c3(1, 1.5708),c4(5, 3.1416);showComplex(c1);showComplex(c2);showComplex(c3);showComplex(c4);测试程序输出: 3, 4, 5, 0.927295 1, -1, 1.41421, -0.785398 -3.67321e-006, 1, 1, 1.5708 -5, -3.67321e-005, 5, 3.14163设计一个可以利用函数对象求任意函数的定积分的接口,并给出测试程序。参考程序: #include#includeconst double PI=3.14159;class IFunction /定义一个抽象类描述接口public:virtual IFunction ()virtual double operator()(double) = 0; class f1: public IFunction /实现类定义 double r;public:f1(double rad)r=rad;double operator()(double x) return sqrt(r*r-x*x); double getr()return r; ;class f2: public IFunction /实现类定义public:f2()double operator()(double x) return sin(x); ;class f3: public IFunction /实现类定义public:f3()double operator()(double x) return x*x*x; ;class f4: public IFunction /实现类定义public:f4()double operator()(double x) return (x+2)/sqrt(2*x+1); ;class f5: public IFunction /实现类定义public:f5()double operator()(double x) return sin(x/2)*sin(x/2); ;class f6: public IFunction /实现类定义public:f6()double operator()(double x) return sqrt(1-sin(2*x); ;double integrate(IFunction & fObj, double a, double b, int n)/a,b)为积分区间 double step=(b-a)/n;double area=0;while(ab)area += fObj(a)*step;a += step;return area;void main()int n; coutn; double result;f1 obj1(2); result = integrate(obj1, 0, obj1.getr(),n);cout result endl;f2 obj2; result = integrate(obj2, 0, PI,n);cout result endl;f3 obj3; result = integrate(obj3, 0, 1,n);cout result endl;f4 obj4; result = integrate(obj4, 0, 4,n);cout result endl;f5 obj5; result = integrate(obj5, 0, PI/2,n);cout result endl;f6 obj6; result = integrate(obj6, 0, PI/2,n);cout result endl; 程序运行结果:指定精度(积分区间个数):100000003.1415920.257.333330.2853970.828426(请写出本题各函数对象所代表的函数并用数学方法验证各积分结果的正确性。)二、实验注意:每道题的难度等级不同,*越多,难度等级越高。可以根据自己的能力,选做恰当难度的题。(每人至少完成4*)1 设计一个抽象基类Worker,并从该基类中派生出计时工人类HourlyWorker和计薪工人类SalariedWorker。每名工人都具有姓名name、年龄age、性别sex和小时工资额pay_per_hour等属性;周薪计算成员函数void Compute_pay(double hours),(其中参数hours为每周的实际工作时数)和用于显示工人的基本信息的标准输出运算符友元函数ostream& operator和输出运算符operator,实现相应图形类对象的形态参数和输出显示图形类对象的基本信息。要求:1. 按照题意定义和实现Shape、Circle、Ellipse、Rectangle、Triangle、Polygon、HouseShape和Ring构成的几何图形类结构。2. 在主函数main()中编写一个用于测试所定义的几何图形类结构中各个类功能的多态性的菜单选择结构,直至选择退出测试,结束程序执行。在菜单选择结构中对选中的几何图形类进行测试的内容和步骤如下: 动态创建选中的几何图形类对象; 为所创建的几何图形输入形态参数; 显示所创建图形的基本信息; 计算并显示所创建图形的周长和面积; 上述操作结束后删除动态创建的几何图形类对象。3. 要求编写编程文档,文档内容包括: 绘制基类Shape和派生类Circle、Ellipse、Rectangle、Triangle、Polygon、HouseShape、Ring的类图,以及它们之间的静态关联图。 各个派生几何图形类的定义描述。 main()的流程图。提示:1. 如果椭圆的长轴 = 2a,短轴 = 2b,则椭圆的周长 1.5(a + b) - ab ,椭圆的面积 = ab。a2tgn2n如果正n边形的边长 = a,则正n边形的面积 = ah,其中h = ,而 = 。2. 屋形类HouseShape是由矩形类Rectangle和三角形类Triangle聚合而成,所以HouseShape的接口操作应借助Rectangle和Triangle的接口操作来实现。同样, 环形类Ring是由圆形类Circle聚合而成,所以Ring的接口操作也应借助Circle的接口操作来实现。难度等级:*3 归纳绘制各类图形所需要的共同属性和操作接口,可以定义一个只为不同图形绘制类提供绘制属性和绘制操作的接口规则,以及为将不同图形绘制类对象连接成一个链表提供连接属性和插入链表操作的接口规则,而不实现任何具体图形绘制操作和对象插入操作的抽象类Figure如下:enum TYPE LINE, CIRCLE, ELLIPSE, ARC, RECTANGLE, TRIANGLE, POLYGON;class FigureLink;/ 超前声明 class Figurefriend class FigureLink;/ FigureLink是连接不同图形绘制类对象的链表类protected:TYPE type;/ 图形类别:直线 = LINE, 圆 = CIRCLE, 椭圆 = / ELLIPSE, 弧 = ARC, 矩形 = RECTANGLE, 三角/ 形 = TRIANGLE, 正多边形 = POLYGONint cx, cy;/ 绘制图形的中心位置坐标int linestyle;/ 画线样式int linewidth;/ 画线宽度int linecolor;/ 画线颜色int fillpattern;/ 封闭图形的填充样式int fillcolor;/ 封闭图形的填充颜色static Figure* ptr;/ 指向将要插入链表的图形绘制对象Figure* next;/ 指向链表中下一个图形绘制对象public:Figure(int x, int y, TYPE tp, int style = SOLID_LINE, int lnwidth = NORM_WIDTH, int lncolor = WHITE, int pattern = EMPTY_FILL, fcolor = BLACK)cx = x;cy = y;type = tp;linestyle = style;fillpattern = pattern;fillcolor = fcolor;linewidth = lnwidth;linecolor = lncolor;virtual Figure() virtual void Draw() = 0;/ 图形绘制操作的接口规则vitural void Insert() = 0;/ 图形绘制类对象插入链表操作的接口规则void show();/ 在图形方式下按指定格式显示图形的各项属性(中/ 心位置坐标属性除外)。;注意,构造函数中为各项绘图属性的缺省值是绘图系统已经预先定义的符号常量,这些符号常量的种类和含义可以参见提示中响应的相应常量表。要求:1. 从Figure定义以下图形绘制类:Line直线、Circle圆、Ellipse椭圆、Arc弧、Rectangle矩形、Triangle三角形、Poligon正多边形。2. 每种图形绘制类除了从基类继承共同属性外,还分别具有描述自身形状和尺寸的属性,每种图形绘制类的新增属性如下:Line类int length;/ 直线长度int angle/ 直线与水平方向的夹角 (以度单位)Circle类int radius;/ 圆半径Ellipse类int horizAxis/ 椭圆水平轴int vertAxis/ 椭圆垂直轴Arc类int radius;/ 弧线半径int stAngle/ 弧线的起点角(以度单位) int endAngle/ 弧线的止点角(以度单位)Rectangle类int length;/ 矩形的长度int width;/ 矩形的宽度Triangle类int side1;/ 三角形的一条边长int side2;/ 三角形的另一条边长int angle/ 两边的夹角(以度单位)Polygon类int pointNum;/ 正多边形的顶点个数int sideLength;/ 正多边形的(顶点之间)边长3. 上述各个派生类的属性(包括所有图形类的共同属性在内)的设置可以通过两个途径实现: 通过构造函数设置为你确定的特定值。 为每个派生类重载函数调用运算符operator(),通过该运算符函数的参数列表为相应图形的各个属性指定设置值。注意,在为各个图形的形态属性赋值前,应检测所设置属性值在屏幕绘制范围内的合法性。4. 要求每种图形的接口函数Draw()将该图形绘制在一个矩形边框的中央,并在边框的左上角显示该图形的类型名称和属性(文字显示操作由成员函数Show完成)。例如调用一个圆的Draw(),显示结果如下:1 Line 2 Circle 3 Ellipse 4 Arc 5 Rectangle 6 Triangle 7 Polygon 8 ExitCircle: Position of center = (320, 240) , Radius = 100Pen style = SOLID_LINEPen width = NORM_WIDTHPen color = REDFill pattern = LTSLASH_FILLFill color = BLUE 注意,上图示中顶部的文字串是程序的主菜单,它不是Draw()的显示内容。5. 各类图形派生类的接口函数Insert()所实现的功能是动态复制一个所操作的图形对象,用于插入链表。例如Circle:Insert()的实现代码可以按如下定义:void Circle:Insert()ptr = new Circle(cx, cy, linestyle, linewidth, linecolor, fillpattern, fillcolor);6. 各类图形派生类的成员函数Show是在调用基类的Show的基础上增加显示图形种类的文字信息。7. 定义一个可以存放各种图形对象的链表类FigureLink。要求该类应该具有如下属性和操作:属性: 链表头指针属性head:该属性应该是Figure类型的指针。操作: 构造操作:创建一个空链表,即设置head = 0。 析构操作:删除链表中的所有图形对象。 判空操作Empty:判断链表中是否存放了图形对象,如果链表中存放了图形对象,则返回true;否则返回false。该操作函数的原型如下: bool Empty(); 插入操作Insert:该操作用于向链表中插入一个图形绘制对象,被插入的对象的地址通过参数传递。该操作函数的原型如下:void Insert(Figure* figureNode); 检索操作Search:该操作用于在链表中检索一个指定类型的图形对象,如果被检索的图形对象存在,则返回该图形对象的地址,否则返回0。被检索图形的类型值通过参数传递。该操作函数的原型如下:Figure* Search(TYPE type);8. 编制一个主函数完成如下工作: 创建一个存放图形对象的链表(FigureLink对象); 创建各个图形类对象插入到链表中; 编写一个菜单选择结构,并通过该菜单选择结构选择测试链表中各种图形的绘制功能,直至选择Exit菜单项退出菜单选择结构,结束程序执行。提示:1. 可以在Turbo C+ 环境中实现该程序需要完成的绘图操作。在Turbo C+ 环境中如何创建一个程序项目,并利用项目管理程序的编写、编译、链接、运行请参阅文档“使用TC建立程序项目”。2. 在控制台屏幕上绘图各类图形时都必须以确定画线样式、宽度、颜色,以及填充样式、颜色进行绘制操作。系统绘图环境中为各种不同的画线和填充属性定义了相应的符号标识常量和相应的库函数进行绘图属性设置: 画线样式和宽度符号标识常量和设置:画线样式和宽度的设置函数原型:void far setlinestyle(int linestyle, unsigned upattern, int thickness);其中的参数的取值:linestyle: 为画线样式,取值范围见下表:符号名常量值线型描述SOLID_LINE0实线DOTTED_LINE1点虚线CENTER_LINE2点划线(中心线)DASHED_LINE3短划虚线USERBIT_LINE4用户定义样式upattern: 为用户定义样式,即linestyle = USERBIT_LINE时,该16位值的0、1排列表示用户指定的画线样式。thickness: 为画线宽度,取值范围见下表:符号名常量值线宽描述NORM_WIDTH0/11个象素宽THICK_WIDTH33个象素宽 画线颜色符号标识常量和设置:画线颜色的设置函数原型:void far setcolor(int color);其中的参数取值:color: 为颜色值,取值范围见下表:符号名常量值颜色符号名常量值颜色BLACK 0黑色DARKGRAY8深灰色BLUE1兰色LIGHTBLUE9浅兰色GREEN2绿色LIGHTGREEN10浅绿色CYAN3青色LIGHTCYAN11浅青色RED4红色LIGHTRED12浅红色MAGENTA5紫色LIGHTMAGENTA13浅紫色BROWN6棕色YELLOW14黄色LIGHTGRAY7浅灰色WHITE15白色 封闭图形的填充样式和颜色符号标识常量和设置:填充样式和颜色的设置函数原型: void far setfillstyle(int pattern, int color); 其中的参数取值: pattern:为填充样式值,取值范围见下表:符号名常量值图案样式EMPTY_FILL 0无填充SOLID_FILL1实心图案LINE_FILL2水平直线图案LTSLASH_FILL3细斜线图案SLASH_FILL4斜线图案BKSLASH_FILL5反斜线图案LTBKSLASH_FILL6细反斜线图案HATCH_FILL7十字交叉线图案XHATCH_FILL8粗十字交叉线图案INTERLEA

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论