虚函数与多态性(110526)_练习题
多态与虚函数 例题

题目:水果类与虚函数多态与虚函数例题1.题目内容与要求①首先设计一个水果类(Fruit)作为基类,成员函数为显示“水果”函数;②然后设计Fruit类的四个派生类:香蕉类(Banana)、苹果类(Apple)、梨子类(Pear)和桃子类(Peach),成员函数分别为显示“香蕉”、“苹果”、“梨子”和“桃子”函数;③最后在主函数中定义这些类的对象,并调用它们的显示函数。
2.类的分析主函数水果类对象 香蕉类对象 苹果类对象 梨子类对象 桃子类对象 显示函数调用水果类显示函数香蕉类显示函数苹果类显示函数梨子类显示函数桃子类显示函数3.类的设计mainFruit f; Banana b; Apple a; Pear p; Peach ph; f=b; f.print(); f=a; f.print(); ……FruitprintBananaprintAppleprintPearprintPeachprint4.基类程序代码// 基类: 水果类class Fruit{public:void print() {cout<< "水果" <<endl; }};// 派生类1: 香蕉类class Banana: public Fruit{ public:void print() {cout<< "香蕉" <<endl;} };// 派生类2: 苹果类class Apple: public Fruit{ public:void print() {cout<< "苹果" <<endl;} };派生类程序代码// 派生类3: 梨子类class Pear: public Fruit{ public:void print() { cout<< "梨子" <<endl;} };// 派生类4: 桃子类class Peach: public Fruit{ public:void print() { cout<< "桃子" <<endl;} };#include <iostream> using namespace std; <5个类的定义在此!>int main() // 主函数 {核心代码在此!return 0; }主函数程序代码Fruit * pFruit[] = { new Fruit(),new Banana(), new Apple(), new Pear(), new Peach() };for(int i = 0; i < 5; i++) { (*pFruit[i]).print(); }❝从以上5行运行结果来看,似乎调用的都是基类的print 函数。
多态练习题

1、生成表示学生的类XS,提供成员函数dispXM()、dispXB()和dispNL()分别用来显示姓名、性别和年龄,并将他们全部定义为纯虚函数;生成CZS类表示初中生,包含数据成员xm、xb和nl表示学生的姓名、性别和年龄,提供成员函数dispXM()、dispXB()和dispNL()分别用来显示姓名、性别和年龄;再生成类GZS表示高中生和类DXS表示大学生,同样包含相同含义的数据成员xm、xb和nl,也包括成员函数dispXM()、dispXB()和dispNL()。
要求:(1)设计和实现基本类XS(2)设计和实现派生类CZS,GZS和DXS(3)分别生成CZS、GZS、DXS类对象(4)将CZS、GZS、DXS类对象的指针赋给指针赋给XS类的指针变量。
(5)分别用XS类的指针和引用访问dispXM()、dispXB()和dispNL()函数。
(6)观察程序结果。
#include <iostream>#include <string.h>using namespace std;class XS{public:virtual void dispXM()=0;virtual void dispXB()=0;virtual void dispNL()=0;};class CZS:public XS{public:CZS(char * m="张三",int b=1,int n=14);void dispXM();void dispXB();void dispNL();protected:char xm[9];int xb,nl;};CZS::CZS(char *m,int b,int n){strcpy(xm,m);xb=b,nl=n;}void CZS::dispXM(){cout<<"name:"<<xm<<endl;}void CZS::dispXB(){if(xb==1)cout<<"Man"<<endl;if(xb==0)cout<<"Woman"<<endl;}void CZS::dispNL(){cout<<"age:"<<nl<<endl;}class GZS:public XS{public:GZS(char * m="张三",int b=1,int n=17);void dispXM();void dispXB();void dispNL();protected:char xm[9];int xb,nl;};GZS::GZS(char *m,int b,int n){strcpy(xm,m);xb=b,nl=n;}void GZS::dispXM(){cout<<"name:"<<xm<<endl;}void GZS::dispXB(){if(xb==1)cout<<"Man"<<endl;if(xb==0)cout<<"Woman"<<endl;}void GZS::dispNL(){cout<<"age:"<<nl<<endl;}class DXS:public XS{public:DXS(char * m="张三",int b=1,int n=20);void dispXM();void dispXB();void dispNL();protected:char xm[9];int xb,nl;};DXS::DXS(char *m,int b,int n){strcpy(xm,m);xb=b,nl=n;}void DXS::dispXM(){cout<<"name:"<<xm<<endl;}void DXS::dispXB(){if(xb==1)cout<<"Man"<<endl;if(xb==0)cout<<"Woman"<<endl; }void DXS::dispNL(){cout<<"age:"<<nl<<endl;}void displayP(XS *p){p->dispXM();p->dispXB();p->dispNL();}void displayR( XS &p){p.dispXM();p.dispXB();p.dispNL();}void main(){CZS czs("赵一",1,12);GZS gzs("钱二",0,15);DXS dxs("孙三",1,18);XS *p;//定义抽象基类的指针变量pp=&czs;//将初中生对象czs的地址赋给pdisplayP(p);p=&gzs;//将高中生对象czs的地址赋给pdisplayP(p);p=&dxs;//将大学生对象czs的地址赋给pdisplayP(p);cout<<"\n----------------------------------------\n";XS &r1=czs;//定义抽象基类的引用变量r1为czs的别名displayR(r1);XS &r2=gzs;//定义抽象基类的引用变量r2为czs的别名displayR(r2);XS &r3=dxs;//定义抽象基类的引用变量r3为czs的别名displayR(r3);cout<<"\n----------------------------------------\n";}2、某小型公司主要有3类人员:经理、兼职技术人员、兼职销售员。
复习题及答案2

一、选择题下列各题A)、B)、C)、D)四个选项中,只有一个选项是正确的。
请将正确选项涂写在答题卡相应位置上,答在试卷上不得分。
(4)下面选项中不属于面向对象程序设计特征的是。
A)继承性B)多态性C)类比性D)封装性(11)为了取代C中带参数的宏,在C++中使用A)重载函数B)内联函数C)递归函数D)友元函数(12)下列关于类定义的说法中,正确的是A)类定义中包括数据成员和函数成员的声明B)类成员的缺省访问权限是保护的C)数据成员必须被声明为私有的D)成员函数只能在类体外进行定义(13)下列关于派生类构造函数和析构函数的说法中,错误的是A)派生类的构造函数会隐含调用基类的构造函数B)如果基类中没有缺省构造函数,那么派生类必须定义构造函数C)在建立派生类对象时,先调用基类的构造函数,再调用派生类的构造函数D)在销毁派生类对象时,先调用基类的析构函数,再调用派生类的析构函数(14)通过运算符重载,可以改变运算符原有的A)操作数类型B)操作数个数C)优先级D)结合性(16)使用输入输出操作符setw,可以控制A)输出精度B)输出宽度C)对齐方式D)填充字符(17)下列字符串中,不可以用作C++标识符的是A)y_2006 B)____TEST__H C)Retum D)switch (18)字面常量42、4.2、42L的数据类型分别是A)long、double int B)long、float、int C)int、double、long D)int、float、long(19)执行下列语句段后,输出字符“*”的个数是for(int i =50;I>1;— i )cout<<”*”A)48 B)49C)50 D)51(20)有如下程序段int i =0, j=1;int &r=i ; // ①r =j; //②int *p=&i ; //③*p=&r ; //④基中会产生编译错误的语句是A)④B)③C)②D)①(21)有如下函数定义:void func (int a,int&b){a++; b++;}若执行代码段:int x=0 ,y=1func(x,y);则变量x和y值分别是A)0和1 B)1和1 C)0和2D)1和2 (22)有如下程序:#include <iostream>using namespace std;class A{public:static int a;void init(){a=1;}A(int a=2){init();a++;}};int A::a=0;A obj;int main(){cout<<A::a;return 0;} 运行时输出的结果是A)0 B)1 C)2 D)3(23)下列有关继承和派生的叙述中,正确的是A)派生类不能访问基类的保护成员B)作为虚基类的类不能被实例化C)派生类应当向基类的构造函数传递参数D)虚函数必须在派生类中重新实现(24)下列运算符中,不能被重载的是A)&&B)!= C).D)++ (26)在语句cin>>data;中,cin是A)C++的关键字B)类名C)对象名D)函数名(27)有如下程序:#include <iostream>using namespace std;class test {private:int a;public:test(){ cout<<"constructor"; }test(int a){ cout<<"constructor"; }test(const test&_test){ a=_test.a;cout<<"copy constructor";}~test(){cout<<"destructor";}};int main(){ test A(3);return 0; }运行时输出的结果是A)3 B)constructor destruclor C)copy constructor D)3 dstructor destruclor(28)若有如下类声明class My Class {public:MyClass(){cout<<1;}};执行下列语句MyClass a,b[2],*P[2];以后,程序的输出结果是A)11 B)111C)1111 D11111(29)有如下程序:#include <iostream>using namespace std;class point{public:static int number;public:point() { number++;} ~point() {number--;}};int point::number=0;void main(){ point *ptr;point A,B;{point *ptr_point=new point[3];ptr=ptr_point;}point C;cout<<point::number;delete[] ptr;}A)3 B)4 C)6D)7(30)如果不使用多态机制,那么通过基类的指针虽然可以指向派生类对象,但是只能访问从基类继承的成员,有如下程序,没有使用多态机制。
习题9及其解答

习题9及其解答9.1 选择题1.在C++中,要实现动态联编,必须使用( d )调用虚函数。
(a) 类名(b) 派生类指针(c) 对象名(d) 基类指针2.下列函数中,不能说明为虚函数的是( c )。
(a) 私有成员函数(b) 公有成员函数(c) 构造函数(d) 析构函数3.在派生类中,重载一个虚函数时,要求函数名、参数的个数、参数的类型、参数的顺序和函数的返回值( a )。
(a) 相同(b) 不同(c) 相容(d) 部分相同4.C++中,根据( d )识别类层次中不同类定义的虚函数版本。
(a) 参数个数(b) 参数类型(c) 函数名(d) this指针类型5.虚析构函数的作用是( c )。
(a) 虚基类必须定义虚析构函数(b) 类对象作用域结束时释放资源(c) delete动态对象时释放资源(d) 无意义6.下面函数原型中,( b )声明了fun为纯虚函数。
(a) void fun()=0; (b) virtual void fun()=0;(c) virtual void fun(); (d) virtual void fun(){ };7.若一个类中含有纯虚函数,则该类称为( c )。
(a) 基类(b) 纯基类(c) 抽象类(d) 派生类8.假设 Aclass为抽象类,下列正确的说明语句是( b )。
(a) Aclass fun( int ) ; (b) Aclass * p ;(c) int fun( Aclass ) ; (d) Aclass Obj ;9.下面描述中,正确的是( d )。
(a) 虚函数是没有实现的函数(b) 纯虚函数是返回值等于0的函数(c) 抽象类是只有纯虚函数的类(d) 抽象类指针可以指向不同的派生类10.构造异质链表的意义是( d )。
(a) 用数组组织类对象(b) 用链表组织类对象(c) 用抽象类指针指向派生类对象(d) 用抽象类指针构造派生类对象链表9.2阅读下列程序,写出执行结果1.#include <iostream>using namespace std;class Bclass{ public:Bclass( int i, int j ) { x = i; y = j; }virtual int fun() { return 0 ; }protected:int x, y ;};class Iclass:public Bclass{ public :Iclass(int i, int j, int k):Bclass(i, j) { z = k; }int fun() { return ( x + y + z ) / 3; }private :int z ;};int main(){ Iclass obj( 2, 4, 10 );Bclass p1 = obj;cout << p1.fun() << endl;Bclass &p2 = obj ;cout << p2.fun() << endl;cout << p2.Bclass :: fun() << endl;Bclass *p3 = &obj;cout << p3 -> fun() << endl;}【解答】552.#include <iostream>using namespace std;class Base{ public:virtual void getxy( int i,int j = 0 ) { x = i; y = j; } virtual void fun() = 0 ;protected:int x , y;} ;class A : public Base{ public:void fun(){ cout<<"x = "<<x<<'\t'<<"y = x * x = "<<x*x<<endl; }};class B : public Base{ public:void fun(){ cout << "x = " << x << '\t' << "y = " << y << endl;cout << "y = x / y = " << x / y << endl;}} ;int main(){ Base * pb;A obj1;B obj2;pb = &obj1;pb -> getxy( 10 );pb -> fun();pb = &obj2;pb -> getxy( 100, 20 );pb -> fun();}【解答】x = 10 y = x*x = 100x = 100 y = 20y = x / y = 59.3 思考题1.在C++中,使用类体系依靠什么机制实现程序运行时的多态?【解答】在C++中,基类指针可以指向派生类对象,以及基类中拥有虚函数,是支持多态性的前提。
C 程序设计与应用基础第五章 多态性习题答案

根据结果将程序补充完整。
#incude <iostream.h>
class Base
{
public:
Base(){cout<<"Base's cons."<<endl;}
___varitual ~Base()___{cout<<"Base's des."<endl;}
};
class Derived:public Base
第五章多态性
1、填空题
1)在一个成员函数内调用一个虚函数时,对该虚函数的调用进行___动态______联编。
2)动态联编是在__虚函数___的支持下实现的,它通过___指针和引用__来调用该函数操作。
3)下列程序的运行结果如下:
Base's cons.
Derived's cons.
Derived's des.
salesman s1;
employee *emp[4]={&m1,&t1,&sm1,&s1};
int i;
for(i=0;i<4;i++)
{
emp[i]->promote();
emp[i]->pay();
emp[i]->display();
}
}
2)编写一个程序,建立两种类型的表:队列与堆钱,使它们可以共用一个接口访问。
答案:
#include <iostream.h>
#include <string.h>
class employee
C++虚函数相关练习及答案分析

代码:
#include <iostream>
using namespace std;
class A
{
public:
A(){cout<<"调用A的构造函数"<<endl;A::func();}
virtual void func(){cout<<"A::func()"<<endl;}
~A(){cout<<"调用A的析构函数"<<endl;}
};
class D
{
public:
D(){cout<<"调用D的构造函数"<<endl;}
void func(){cout<<"D::func()"<<endl;}
~D(){cout<<"调用D的析构函数"<<endl;}
};
class B:public A
};
class B:public A
{
public:
B(){cout<<"调用B的构造函数"<<endl;B::func();}
void func(){cout<<"B::func()"<<endl;}
~B(){cout<<"调用B的析构函数"<<endl;}
D d;
};
class C:public B
~A(){cout<<"调用A的析构函数"<<endl;}
《Java程序设计案例教程》第十章练习答案

第10章多态性与虚函数一、单项选择题1.实现运行时的多态性要使用(D)。
A.重载函数B.构造函数C.析构函数D.虚函数2.通过运算符重载,可以改变运算符原有的(A)。
A.操作数类型B.操作数个数C.优先级D.结合性3.将运算符重载为类成员函数时,其参数表中没有参数,说明该运算符是(B)。
A.不合法的运算符B.一元运算符C.无操作数的运算符D.二元运算符4.在重载一个运算符时,其参数表中没有任何参数,说明该运算符是(B)。
A.作为友元函数重载的一元运算符B.作为成员函数重载的一元运算符C.作为友元函数重载的二元运算符D.作为成员函数重载的二元运算符5.如果表达式++a中的"++"是作为成员函数重载的运算符,若采用运算符函数调用格式,则可表示为(D)。
A.a.operator++(1)B.operator++(a)C.operator++(a,1)D.a.operator++()6.如果表达式a>=b中的">="是作为非成员函数重载的运算符,则可以等效地表示为(C)。
A.a.operator>=(b)B.b.operator>=(a)C.operator>=(a,b)D.perator>=(b,a)7.有如下程序:#include<iostream>using namespace std;class A{public:virtual void funl (){cout<<"A1";}void fun2 (){cout<<"A2";}};class B: public A{public:void funl (){cout<<"Bl";}void fun2 (){cout<<"B2";}};int main(){A*p=new B;p->funl ();p->fun2();return 0;}程序执行后,输出结果为(C)。
C++多态练习题

C++多态练习题⼀、填空题(1)C++的两种联编⽅式为:动态联编和静态联编。
(2)C++⽀持两种多态性,静态联编所⽀持的多态性被称为编译时的多态性、动态联编所⽀持的多态性被称为运⾏时的多态性。
(3)重载函数在编译时表现出多态性,是静态联编;⽽虚函数则在运⾏时表现出多态性是动态联编。
(4)为了区分重载函数,把⼀个派⽣类中重定义基类的虚函数称为覆盖。
(5)如果派⽣类与基类的虚函数仅仅返回类型不同,其余相同,则c++认为是使⽤了不恰当的虚函数。
(6)在构造函数和析构函数中调⽤虚函数时,采⽤静态联编。
(7)纯函数的定义是在虚函数定义的基础上,再让函数等于0 。
(8)对于包含有纯虚函数的类被称为抽象类。
⼆、选择题(⾄少选⼀个,可以多选)(1)⽤关键字(A)标记的函数被称为虚函数。
A.virtualB.privateC.publicD.protected(2)在C++中,要实现动态联编,必须使⽤(D)调⽤虚函数。
A.类名B.派⽣类指针C.对象名D.基类指针(3)下列函数中,可以作为虚函数的是(BD)。
A.普通函数B.⾮静态成员函数C.构造函数D.析构函数(4)在派⽣类中,重载⼀个虚函数时,要求函数名、参数的个数、参数的类型、参数的顺序和函数的返回值(B)。
A.不同B.相同C.相容D.部分相同(5)使⽤虚函数保证了在通过⼀个基类类型的指针(含引⽤)调⽤⼀个虚函数时,c++系统对该调⽤进⾏(A),但是,在通过⼀个对象访问⼀个虚函数,使⽤(B)。
A.动态联编B.静态联编C.动态编译D.静态编译(6)下⾯函数原型声明中,(C)声明的fun()为纯虚函数。
A.void func()=0;B.virtual void func()=0;B.virtual void func();C.virtual void func(){};(7)若⼀个类中含有纯虚函数,则该类称为(C)。
A.基类B.虚基类C.抽象类D.派⽣类(8)假设Myclass为抽象类,下列声明(CD)是错误的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3、(选做题) 某学校对教师每月工资的计算规定如下:固定工作+课时补 贴。教授的固定工作为5000元,每个课时补贴50元;副教授 的固定工资为3000元,每个课时补贴30元;讲师的固定工资 为2000元,每个课时补贴20元。定义教师抽象类,派生不同 职称的教师类,编写程序求若干个教师的月工资。
#include<iostream.h> class Rational { public : Rational (long n , long d=1) ; // 构造函数,把长整型转换成Rational类型 friend Rational operator+ ( const Rational & ,const Rational & ) ; friend ostream &operator<<(ostream &os, Rational &s); operator double() ; // 类型转换函数 private : long Numerator , Denominator ; }; Rational :: Rational(long n, long d) { Numerator = n ; Denominator = d ; } Rational :: operator dou Numerator ) / double( Denominator ); } Rational operator+ ( const Rational & r1, const Rational & r2 ) { long n , d ; n = r1.Numerator * r2.Denominator + r1.Denominator * r2.Numerator ; d = r1.Denominator * r2.Denominator ; return Rational( n, d ) ; }
实验内容——作业 作业 实验内容 1、编写一个程序,定义抽象基类Shape,由它派生出5个 派生类:Circle(圆形)、Square(正方形)、Rectangle(矩形 )、Trapezoid(梯形)、Triangle(三角形)。用虚函数分别计 算几种图形面积。要求用基类指针数组,使它每一个元 素指向一个派生类对象。 2 2、使用虚函数编写程序,求球体和圆柱体的体积和表面 积。由于球体和圆柱体都可以看做由圆继承而来,所以 可以定义圆类circle作为基类。在circle类中定义一个数 据成员radius和两个虚函数area()和volume()。由circle类 派生sphere类和column类。在派生类中对虚函数area()和 volume()重新定义,分别求球体和圆柱体的体积及表面 积。
ostream &operator<<(ostream &os, Rational &s) { os << s.Numerator << "/" << s.Denominator ; return os; } void main ( ) { Rational a( 2, 4 ), b = (1, 2), c( 0 ) ; c = a + b; // 使用友员重载 “+” 和 缺省重载 “=”