c多态性与虚函数习题
- 格式:doc
- 大小:21.50 KB
- 文档页数:4
题目:水果类与虚函数多态与虚函数例题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.#include<iostream>using namespace std;class A {public:virtual void func( ) {cout<<”func in class A”<<endl;} };class B{public:virtual void func( ) {cout<<”func in class B”<<endl;} };class C:public A,public B{public:void func( ) {cout<<”func in class C”<<endl:}};int main( ){C c;A& pa=c;B& pb=c;C& pc=c;pa.func( );pb.func( );pc.func( );}2.#include<iostream>using namespace std;class A{public:virtual ~A( ){cout<<”A::~A( ) called “<<endl; }};class B:public A{char *buf;public:B(int i) { buf=new char[i]; }virtual ~B( ){delete []buf;cout<<”B::~B( ) called”<<endl;}};void fun(A *a) {delete a;}int main( ){ A *a=new B(10);fun(a);}二、程序设计题1有一个交通工具类vehicle,将它作为基类派生小车类car、卡车类truck和轮船类boat,定义这些类并定义一个虚函数用来显示各类信息。
5.2定义一个shape抽象类,派生出Rectangle类和Circle类,计算各派生类对象的面积Area( )。
C++习题3(继承和多态)C++习题3(继承和多态)一、选择题1、在C++中,类与类之间的继承关系具有( C )A)自反性 B)对称性 C)传递性 D)反对称性2、在公有继承的情况下,基类的成员(私有的除外)在派生类中的访问权限( B )A)受限制 B)保持不变 C)受保护 D)不受保护3、按解释中的要求在下列程序划线处填入的正确语句是:( C )#include class Base{public:void fun(){cout<<"Base::fun"<<=""> fun()cout<<"Derived::fun"<fun();4、在保护继承的情况下,基类的成员(私有的除外)在派生类中的访问权限( C )A)受限制 B)保持不变 C)受保护 D)不受保护5、在哪种派生方式中,派生类可以访问基类中的protected 成员(B )A)public和private B)public、protected和private C)protected和private D)仅protected6、当一个派生类仅有protected继承一个基类时,基类中的所有公有成员成为派生类的(C)A)public成员 B)private成员 C)protected成员 D)友元7、不论派生类以何种方法继承基类,都不能使用基类的(B )A)public成员 B)private成员 C)protected成员 D)public成员和protected成员8下面叙述错误的是(S )。
A )基类的protected成员在派生类中仍然是protected的 B)基类的protected成员在public派生类中仍然是protected的C)基类的protected成员在private派生类中是private的 D)基类的protected 成员不能被派生类的对象访问9、下列说法中错误的是(S )。
多态性与虚函数习题一、选择题1.在C++中,用于实现运行时多态性的是()。
A)内联函数B)重载函数C)模板函数D)虚函数2.如果一个类至少有一个纯虚函数,那么就称该类为()。
(a)抽象类 (b)派生类 (c)虚基类 (d)以上都不对3.为了区分一元运算符的前缀和后缀运算,在后缀运算符进行重载时,额外添加一个参数,其类型是()。
(a)void (b)char (c)int (d)float4.下列关于抽象类的说明中不正确的是()。
(a)含有纯虚函数的类称为抽象类(b)抽象类不能被实例化,但可声明抽象类的指针变量(c)抽象类的派生类可以实例化(d)纯虚函数可以被继承5.运行下列程序的输出结果为()。
#include<iostream.h>class base{public:void fun1(){cout<<"base"<<endl;}virtual void fun2(){cout<<"base"<<endl;}};class derived:public base{public:void fun1(){cout<<"derived"<<endl;}void fun2(){cout<<"derived"<<endl;}};void f(base &b){b.fun1();b.fun2();}int main(){derived obj;f(obj);return 0;}(a)base (b)base (c)derived (d)derivedBase derived base derived6.下面描述中,正确的是()。
A.virtual可以用来声明虚函数B.含有纯虚函数的类是不可以用来创建对象的,因为它是虚基类C.即使基类的构造函数没有参数,派生类也必须建立构造函数D.静态数据成员可以通过成员初始化列表来初始化7. 关于虚函数的描述中,正确的是()。
第十二章多态性与虚函数一、选择题1、下面哪个不能实现多态(C )。
A)函数重载 B)虚函数 C)虚基类 D)运算符重载2、下面有关抽象类的说法不正确的是( A )。
A)抽象类是可以定义对象的B)抽象类通常作为基类使用C)抽象类处于继承层次结构的较上层D)抽象类刻画了一组子类操作的通用接口3、下面有关纯虚函数的说法错误的是( D )。
A)派生类可以不重新定义纯虚函数B)运算符重载函数可以被定义为纯虚函数C)纯虚函数可以被重载D)基类中的纯虚函数在派生类的对象中无法访问4、关于虚函数,正确的描述是(A )。
A)构造函数不能是虚函数B)析构函数不能是虚函数C)虚函数可以是友元函数D)虚函数是静态成员函数5、如果在基类中将show()函数声明为不带返回值的纯虚函数,正确的写法是( C )。
A)virtual show()=0;B)virtual void show();C)virtual void show()=0;D)void show()=0 virtual;6、关于动态联编的描述中,( D )是错误的。
A) 动态联编是以虚函数为基础的B) 动态联编是在运行时,确定所调用的函数代码的。
C) 动态联编调用函数操作是通过指向对象的指针或对象的引用实现的。
D) 动态联编是在编译时确定操作函数的。
7、下列关于抽象类的使用中,( A )是错误的。
A) 可以定义抽象类的对象 B) 可以定义抽象类的指针C) 可以定义抽象类的引用 D) 可以定义抽象类的派生类8、关于虚函数的描述中,(C )是正确的。
A) 虚函数是一个非static类的成员函数。
B) 虚函数是一个非成员函数。
C) 基类中说明了虚函数后,派生类中与其对应的函数可以不必说明为虚函数。
D) 派生类的虚函数与基类的虚函数具有不同的参数个数和类型。
9、关于纯虚函数和抽象类的描述中,( C )是错误的。
A) 纯虚函数是一种特殊的虚函数,它没有具体的实现。
B) 抽象类是指含有纯虚函数的类。
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)是错误的。
多态性10.2 典型例题分析与解答例题1:指出下列对定义重载函数的要求中,哪些是错误的提法。
A.要求参数的个数不同。
B.要求参数中至少有一个类型不同。
C.求函数的返回值不同。
D. 要求参数的个数相同时,参数类型不同。
答案: C例题3:下面关于友元的描述中,错误的是()。
A. 友元函数可以访问该类的私有数据成员B. 一个类的友元类中的成员函数都是这个类的友元函数C. 友元可以提高程序的运行效率D. 类与类之间的友元关系可以继承答案:D1例题4:下述静态成员的特性中,()是错误的。
A. 静态成员函数不能利用this指针B. 静态数据成员要在类体外进行初始化C. 引用静态数据成员时,要在静态数据成员名前加<类名>和作用域运算符D. 静态数据成员不是所有对象所共有的答案:D例题5:关于虚函数的描述中,()是正确的。
A. 虚函数是一个静态成员函数B. 虚函数是一个非成员函数C. 虚函数既可以在函数说明时定义,也可以在函数实现时定义D. 派生类的虚函数与基类中对应的虚函数具有相同的参数个数和类型参考答案:D2例题11:分析下列程序的输出结果。
#include <iostream.h>class A{public:A() { cout<<"A's cons."<<endl; }virtual ~A() { cout<<"A's des."<<endl; }virtual void f() { cout<<"A's f()."<<endl; } void g() { f(); }};class B : public A{public:B() { f(); cout<<"B's cons."<<endl; }3~B() { cout<<"B's des."<<endl; }};class C : public B{public:C() { cout<<"C's cons."<<endl; }~C() { cout<<"C's des."<<endl; }void f() { cout<<"C's f()."<<endl; }};void main(){ A *a=new C;a->g();delete a;}4运行结果:A's cons.A's f().B's cons.C's cons.C's f().C's des.B's des.A's des.10.3 教材习题解答1.选择题(1)下列关于动态联编的描述中,错误的是()。
第9章习题一、概念题1. 解答要点如下。
多态是指同样的消息被不同类型的对象接收时导致完全不同的行为,是对类的特定成员函数的再抽象。
C++支持的多态有多种类型,重载(包括函数重载和运算符重载)和虚函数是其中主要的方式。
2. 解答要点如下。
含有纯虚函数的类称为抽象类。
抽象类的主要作用是通过它为一个类族建立一个公共的接口,使它们能够更有效地发挥多态特性。
抽象类声明了一组派生类共同操作接口的通用语义,而接口的完整实现,即纯虚函数的函数体,要由派生类自己给出,抽象类只能作为基类被继承使用。
抽象类的派生类不一定要给出纯虚函数的实现,没有给出纯虚函数的实现的派生类仍然还是抽象类。
3. 解答要点如下。
在C++中不能声明虚构造函数。
多态是不同的对象对同一消息有不同的行为特性,虚函数作为运行过程中多态的基础,主要是针对对象的,而构造函数是在对象产生之前运行的,因此虚构造函数是没有童义的。
在C++中可以声明虚析构函数。
析构函数的功能是在该类对象消亡之前进行一些必要的清理工作,如果一个类的析构函数是虚函数,那么,由它派生而来的所有子类的析构函数也是虚函数。
析构函数设置为虚函数之后,在使用指针引用时可以动态联编,实现运行时的多态,保证使用基类的指针就能够调用适当的析构函数对不同的对象进行清理工作。
二、填空题1. 运行时2. 静态联编,动态联编3. public vehicle ,public vehicle4. 基类 A中的成员函数.派生类B中的成员函数.5. C类 B类6.抽象函数三、编程题1.#include<iostream.h>class Shape{public:virtual double GetArea()=0;};class Circle:public Shape{double radius;public:Circle(double r):radius(r){}double GetArea(){return 3.1416*radius*radius;}};class Square:public Rectangle{public:Square(double l):Rectangle(l,l){}};int main(){Rectangle r(3.5,4.0);Circle c(2.0);Square s(5.0);cout<<r.GetArea()<<endl;cout<<c.GetArea()<<endl;cout<<s.GetArea()<<endl;return 0;}2.#include <iostream.h>#include <string.h>class Computer{protected:char CPU[20],HDisk[20],Mem[20];public:Computer(char c[],char h[],char m[]){strcpy(CPU,c);strcpy(HDisk,h);strcpy(Mem,m);}virtual void Show(void){cout<<"CPU:"<<CPU<<'\t'<<"HDisk:"<<HDisk<<'\t'<<"Mem:"<<Mem<<endl;}};class PC:public Computer{private:char Display[20],Keyboard[20];public:PC(char c[],char h[],char m[],char d[],char k[]):Computer(c,h,m){strcpy(Display,d);strcpy(Keyboard,k);}void Show(void){cout<<"CPU:"<<CPU<<'\t'<<"HDisk:"<<HDisk<<'\t'<<"Mem:"<<Mem<<endl;cout<<"Display:"<<Display<<'\t'<<"Keyboard:"<<Keyboard<<endl;}};class NoteBook:public Computer{private:char LCD[20];public:NoteBook(char c[],char h[],char m[],char l[]):Computer(c,h,m){strcpy(LCD,l);}void Show(void){cout<<"CPU:"<<CPU<<'\t'<<"HDisk:"<<HDisk<<'\t'<<"Mem:"<<Mem<<endl;cout<<"LCD:"<<LCD<<endl;}};void main(void){PC pc("赛扬1G","Seagate40G","HY256MSDRAM","AOC15","美上美");NoteBook nb("P4/2G","金钻/80G(7200)","DDR/256M","飞利普107T/107F4");Computer *p;p=&pc;p->Show();p=&nb;p->Show();}3.class Computer{protected:char CPU[20],HDisk[20],Mem[20];public:Computer(char c[],char h[],char m[]){strcpy(CPU,c);strcpy(HDisk,h);strcpy(Mem,m);}virtual void Show(void)=0; };。
本文作者:黄邦勇帅学习本文首先你应熟悉C++中的构造函数,基本的类的声明及怎样初始化类,关于这些问题,请参看本人所作的《C++构造函数,复制构造函数和析构函数》一文,在这篇文章中作了详细的介绍。
本文分两部分即继承和虚函数与多态性,本文第一部分详细讲解了继承时的构造函数和析构函数的问题,父类与子类的同名变量和函数问题,最后介绍了多重继承与虚基类。
本文第二部分重点介绍了虚函数与多态性的问题,因此学习虚函数的基础是继承,因此在学习虚函数前应学好继承。
本文详细易懂,内容全面,是学习C++的不错的资料。
本文内容完全属于个人见解与参考文现的作者无关,其中难免有误解之处,望指出更正。
声明:禁止抄袭本文,若需要转载本文请注明转载的网址,或者注明转载自“黄邦勇帅”。
主要参考文献:1、C++.Primer.Plus.第五版.中文版[美]Stephen Prata著孙建春韦强译人民邮电出版社2005年5月2、C++.Primer.Plus.第四版.中文版Stanley B.Lippman、Barbara E.Moo著李师贤等译人民邮电出版社2006年3月3、C++.Primer.Plus.第三版.中文版Stanley B.Lippman等著潘爱民张丽译中国电力出版社2002年5月4、C++入门经典第三版[美]Ivor Horton著李予敏译清华大学出版社2006年1月5、C++参考大全第四版[美]Herbert Schidt著周志荣朱德芳于秀山等译电子工业出版社2003年9月6、21天学通第四版C++ [美]Jesse Liberty著康博创作室译人民邮电出版社2002年3月14 继承(基类,父类,超类),派生类,子类一:继承中的访问权限关系。
1.基类,父类,超类是指被继承的类,派生类,子类是指继承于基类的类.2.在C++中使用:冒号表示继承,如class A:public B;表示派生类A从基类B继承而来3.派生类包含基类的所有成员,而且还包括自已特有的成员,派生类和派生类对象访问基类中的成员就像访问自已的成员一样,可以直接使用,不需加任何操作符,但派生类仍然无法访问基类中的私有成员.4.在C++中派生类可以同时从多个基类继承,Java不充许这种多重继承,当继承多个基类时,使用逗号将基类隔开.5.基类访问控制符,class A:public B基类以公有方式被继承,A:private B基类以私有方式被继承,A:protected B基类以受保护方式被继承,如果没有访问控制符则默认为私有继承。
第9章多态性和虚函数的使用一、选择题1.C. 2.C 3.A 4.C 5. 6.D二、程序题(略)三、简答题1.C++多态性主要体现在哪两个方面?答:在C++中,多态性是指系统调用同名的函数,实现不同的功能。
多态性包含静态多态性和动态多态性。
静态多态性体现在编译时函数重载或者运算符重载上;展现了同一类中多个同名函数的处理机制。
而动态多态性是指程序运行过程中通过虚函数动态地确定针对的对象,展现继承层次结构中同名函数的处理机制。
2. 比较函数重载和虚函数在概念上和使用方式有什么区别。
函数重载是指函数名称相同,但是参数的个数或者参数的数据类型不同。
因此,系统调用重载函数时,会依据参数确定调用哪一个。
而在继承的机制中,基类的成员函数可能会与派生类新增的成员函数同名,包括参数个数和参数类型,这种现象不属于函数重载。
当基类的一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。
派生类可以对虚函数重新定义。
虚函数实现动态多态的问题。
3.比较抽象类、虚函数、纯虚函数的概念和使用上的区别。
虚函数通常在基类中定义,定义可以是空,派生类中可以对虚函数重写,也可以不写。
虚函数起到了接口的默认行为作用。
纯虚函数在基类中是没有定义的,必须在直接或者间接派生类中加以实现,它起到了接口的作用。
包含了纯虚函数的类,被称为抽象类。
抽象类不能建立对象。
4.谈谈虚基类和虚函数,区分两者不同的概念和各自的作用。
在继承机制中,一个派生类继承多个直接基类,而这些基类又有一个公共的基类,这个公共的基类成员在继承中可能产生多个拷贝。
虚基类的基本原则是在内存中只有基类成员的一份拷贝。
这样,通过把基类继承声明为虚拟的,就只能继承基类的一份拷贝,从而消除歧义。
用virtual限定符把基类继承说明为虚拟的。
虚函数指基类中成员函数声明为 virtual ,使它在一个或多个派生类中被重新定义,虚函数的作用是实现多态性。
虚函数必须是基类的非静态成员函数,其访问权限可以protected或public。