c++多态性与虚函数习题
多态与虚函数 例题
题目:水果类与虚函数多态与虚函数例题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 函数。
C++课后习题及其答案
练习题11.1 判断题×1.C++语言和C语言都是面向对象的程序设计语言。
√2.面向对象方法具有封装性、继承性和多态性。
√3.C语言是C++语言的一个子集。
C++语言继承了C语言。
×4.C++语言程序与C语言程序一样都是函数串。
×5.C++语言支持封装性和继承性,不支持多态性。
√6.C++语言比C语言对数据类型要求更加严格了。
√7.C++语言对C语言进行了一次改进,使得编程更加方便了。
×8.C++源程序在编译时可能出现错误信息,而在连接时不会出现错误信息。
√9.编译C++源程序时,出现了警告错(Warning)也可以生成可执行文件。
√10.C++语言程序的实现也要经过编辑、编译连接和运行3个步骤。
1.2 单选题1.下列关于面向对象概念的描述中,错误的是(C )。
A.面向对象方法比面向过程方法更加先进B.面向对象方法中使用了一些面向过程方法中没有的概念C.面向对象方法替代了结构化程序设计方法D.面向对象程序设计方法要使用面向对象的程序设计语言2.下列各种高级语言中,不是面向对象的程序设计语言是(D )。
A.C++ B.JavaC.VB D.C3.下列关于类的描述中,错误的是( A )。
A.类就是C语言中的结构类型B.类是创建对象的模板C.类是抽象数据类型的实现D.类是具有共同行为的若干对象的统一描述体4.下列关于对象的描述中,错误的是(C )。
A.对象是类的一个实例B.对象是属性和行为的封装体C.对象就是C语言中的结构变量D.对象是现实世界中客观存在的某种实体5.下列关于C++程序中使用提取符和插入符的输入/输出语句的描述中,错误的是(C )。
A.提取符是对右移运算符(>>)重载得到的B.插入符是对左移运算符(<<)重载得到的C.提取符和插入符都是双目运算符,它们要求有两个操作数D.提取符和插入符在输入/输出语句中不可以连用1.3 填空题1.C++语言具有面向对象方法中要求的三大特性:封装性、继承性和多态性。
C++面向对象程序设计第九章多态性与虚函数
13
【例9.1】虚函数的作用(改造例8.11)(P278)
class graduate:public undergraduate, public teacher // 从两个类继承 {public: void setinfo(int n, char* strname, char s, char* strfrom, float sc, float sa) { id = n; strcpy(name, strname); sex = s; strcpy(from, strfrom); score = sc; salary = sa; } graduate( ) { setinfo(1, "jetty", 'M', "china", 90, 1000); } void showinfo() { cout<<endl<<"ID: "<<id<<endl<<"name: "<<name <<endl<<"sex: "<<sex<<endl<<"from: "<<from <<endl<<"score: "<<score <<endl<<"salary: "<<salary; } };
8
9.3
纯虚函数与抽象类
被标明为不具体实现的虚成员函数为纯虚函数;其声明格式为: 被标明为不具体实现的虚成员函数为纯虚函数;其声明格式为: virtual 函数类型 函数名 参数表 ; 函数名(参数表 参数表)=0; 不能有实例对象的类即为抽象类,唯一的用途是被继承,一个抽 不能有实例对象的类即为抽象类,唯一的用途是被继承, 象类至少具有一个虚函数。 象类至少具有一个虚函数。 抽象类为抽象和设计的目的而建立, 抽象类为抽象和设计的目的而建立,将有关的数据和行为组织在 一个继承层次结构中,保证派生类具有要求的行为。 一个继承层次结构中,保证派生类具有要求的行为。对于暂时 无法实现的函数,可以声明为纯虚函数,留给派生类去实现。 无法实现的函数,可以声明为纯虚函数,留给派生类去实现。 派生类实现纯虚函数的参数要与父类纯虚函数声明的参数相同。 派生类实现纯虚函数的参数要与父类纯虚函数声明的参数相同。 抽象类不能定义对象,但可以声明抽象类的指针或引用。 抽象类不能定义对象,但可以声明抽象类的指针或引用。通过改 变指针或引用的具体地址,指向相应的派生类的对象, 变指针或引用的具体地址,指向相应的派生类的对象,以便实 现运行时的多态。 现运行时的多态。 派生类如果没有定义全部纯虚函数的操作,继承了部分纯虚函数, 派生类如果没有定义全部纯虚函数的操作,继承了部分纯虚函数, 则仍然是抽象类。 则仍然是抽象类。 【例9.3】纯虚函数和抽象类 】
C--程序设计--第10章-多态性及虚函数
使用重载函数注意:
不要使用重载函数描述不相干的函数 在类中,构造函数和普通成员函数均可以
重载 避免与函数的默认参数产生二义性
二、运算符重载
运算符重载(operate overloading)就是 赋予已有的运算符多重含义。
运算符重载实质是函数重载,运算符重载 的选择与函数重载类似,会根据运算符的 操作数的类型、个数和顺序来进行运算符 函数的选择。
#include<iostream.h> str#iinngc:l:usdter<isntgr(icnhga.rh>*s) v{}ossccsssc{s{{ittohtttolsstlsssls*drruarrrueptrepttepsi1trii3tc{pn=rin=rrn=pmn.<nn.<lprgncngncign=agp<*ggp<auitepgtepnte'irssrssbv\hwy:hwyghwnsit1ssitsla0=(:=(:=(tnr=ttnrit'scssscs:sc)rt1"rrt3scesss~ivci;thpt1hpsih1(.T23(.t::tttsnohn}ra,r.a,tza()gh(()grrrrttiatlrsilrsrer";eass;eiiiirdre[)ne[1i;[Ttt1ttnnnniglnl;gnl.nlhl)rlggggnep*e(e}(gesgeiei;2e(((gtrsnsnstnp(nsns)ncsi(lipg)gthg)ig(;(htn)en;t;tr;t;nti)a)artnthhih}ths<<ri{((;+n++<p<snd))}1g1s1aere*ige;]]i]nonszl{{;&;z;ddgd)&eercseelrl;s=teo1)m;a;/18etu)om/)0ut..;)构sr<""/;pn<造);//;s;/复}lp函构e<制n<数造ge构tn函hd造;l数};重} 载
多态性与虚函数习题
多态性与虚函数习题一、选择题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. 关于虚函数的描述中,正确的是()。
第12章 多态性与虚函数补充习题
第十二章多态性与虚函数一、选择题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 程序设计与应用基础第五章 多态性习题答案
根据结果将程序补充完整。
#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;}
C++(练习)第9章,多态性与虚函数
B虚函数
C派生类
D其他都不对
参考答案
A
5.关于虚函数的描述中,()是正确的。
A虚函数是一个静态成员函数
B虚函数是一个非成员函数
C虚函数既可以在函数说明时定义,也可以在函数实现时定义
D派生类的虚函数与基类中对应的虚函数具有相同的参数个数和类型
参考答案
D
6.下面4个选项中,()是用来声明虚函数的。
C virtual void tt(int);
D virtual void tt(int){ };
参考答案
A
二.填空题
1.如果类包含了一个或多个__1__,则它是抽象类。
参考答案
1:纯虚函数
2.虚函数必须是类的__1__。
参考答案
1:非静态成员函数或成员函数
3.多态性分为两类:编译时的多态性和__1__的多态性。
参考答案
1:友元函数
7.如果在类中定义了一个成员函数为__1__,则表明在该继承层次链条的派生类中有可能重新定义这个成员函数的实现,即它可能被派生类的同名函数所覆盖。
参考答案
1:虚函数
8.动态多态性通过__1__实现。
参考答案
1:虚函数
9.定义一个函数名为fun,返回值为int,没有参数的纯虚函数的定义是__1__。
参考答案
1:引用或指针
20.含有纯虚函数的类称为__1__。
参考答案
1:抽象类
21.在C++中,编译时的多态性是通过函数重载和__1__体现的。
参考答案
1:模板
三.问答题
四.编程题
参考答案
1:纯虚函数
12.虚函数必须是类的__1__。
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)是错误的。
c++多态性相关习题
多态性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)下列关于动态联编的描述中,错误的是()。
多态性例题
多态性1 知识要点1.多态性:多态是指同样的消息被不同类型的对象接收后导致完全不同的行为。
2.面向对象的多态性可以分为4类:重载多态、强制多态、包含多态和参数多态。
3.多态从实现的角度来讲可以划分为两类:编译时的多态和运行时的多态。
4.运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据导致不同类型的行为。
5.运算符重载的规则如下:1)C++语言中的运算符除了少数几个之外,全部可以重载,而且只能重载C++语言中已有的运算符。
2)重载之后运算符的优先级和结合性都不会改变。
3)运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。
一般来讲,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。
不能重载的运算符只有5个,它们是类属关系运算符“.”、成员指针运算符“*”、作用域分辨符“::”、sizeof运算符和三目运算符“?:”。
前面两个运算符保证了C++语言中访问成员功能的含义不被改变。
作用域分辨符和sizeof运算符的操作数是类型,而不是普通的表达式,也不具备重载的特征。
6.运算符的重载形式有两种,重载为类的成员函数和重载为类的友元函数。
运算符重载为类的成员函数的一般语法形式为:函数类型 operater 运算符(形参表){ 函数体;}运算符重载为类的友元函数的一般语法形式为:friend 函数类型 operater 运算符(形参表){ 函数体;}7.虚函数说明虚函数的一般格式如下:virtual <函数返回类型说明符> <函数名>(<参数表>)在定义虚函数时要注意:(1) 虚函数是非静态的、非内联的成员函数,而不能是友元函数,但虚函数可以在另一个类中被声明为友元函数。
(2) 虚函数声明只能出现在类定义的函数原型声明中,而不能在成员函数的函数体实现的时候声明。
(3) 一个虚函数无论被公有继承多少次,它仍然保持其虚函数的特性。
(笔试题)关于C++的虚函数和多态性
(笔试题)关于C++的虚函数和多态性以下两段程序的输出是什么?程序1:#include "stdio.h"class Base{public:int Bar(char x){return (int)(x);}virtual int Bar(int x){return (2 * x);}};class Derived : public Base{public:int Bar(char x){return (int)(-x);}int Bar(int x){return (x / 2);}};int main(void){Derived Obj;Base *pObj = &Obj;printf("%d,", pObj->Bar((char)(100)));printf("%d,", pObj->Bar(100));}分析:答案:100 50Derived Obj;Base *pObj = &Obj;printf("%d,", pObj->Bar((char)(100)))printf("%d,", pObj->Bar(100));第⼀个Bar(char)是⾮虚函数,因此是静态绑定,静态绑定是指指针指向声明时的对象,pObj声明时为Base类,因此调⽤的是Base类的Bar(char)第⼆个Bar(char)是虚函数,因此是动态绑定,动态绑定是指指针指向引⽤的对象,pObj引⽤Derived对象,因此调⽤的是Derived类的Bar(int)程序2:#include <iostream>using namespace std;class animal{protected:int age;public:virtual void print_age(void) = 0;};class dog : public animal{public:dog(){ this->age = 2; }~dog(){}virtual void print_age(void){ cout << "wang. my age=" << this->age << endl; }};class cat:public animal{public :cat(){ this->age = 1; }~cat(){}virtual void print_age(void){ cout << " Miao,my age= " << this->age << endl; }};int main(void){cat kitty;dog jd;animal *pa;int *p = (int *)(&kitty);int *q = (int *)(&jd);//cout << p[1] << endl;//cout << q[1] << endl;p[1] = q[1];pa = &kitty;pa->print_age();return 0;}分析:答案:Miao, my age =2int*p = (int*)(&kitty);int*q = (int*)(&jd);p和q是分别指向kitty和jd两个对象的⾸地址,因为类Cat和Dog都包含虚函数,所以kitty和jd两个对象均包含⼀个虚函数表,并通过⼀个指针指向它,p[0]和q[0]就是该虚函数表指针,⽽p[1]和q[1]则为该对象的数据成员即age的值,p[1]=1,q[1]=2p[1] = q[1]=2;kitty的age被修改为2,animal *pa;pa = &kitty;pa->print_age();pa指针声明时的类型为基类animal,它指向派⽣类kitty对象,典型的多态特性,则pa的静态类型为animal,动态类型为cat。
c++练习题实验7 多态性和运算符重载.
employee *ptr[3]={&m1,&t1,&s1};
for(int i=0;i<3;i++)
ptr[i]->displayStatus();
}
1.完善【实例2】程序,写出实现以下功能的代码并上机调试。
(1)将成员函数displayStatus设置成虚函数,运行程序,观察运行结果。体会如何正确使用虚函数实现运行时的多态性。
根据题目要求,设计一个基类Employee,然后派生出Technician(兼职技术人员)类、Manager(经理)类和Salesman(兼职销售员)类。
#include <iostream.h>
#include <string>
using namespace std;
/////////////定义职员基类
{
hourlyRate=100; //每小时酬金100元
}
void technician::pay()
{
cout<<"输入本月工作时数:";cin>>workHours;
sumPay=hourlyRate*workHours;//月薪=工作小时*每小时酬金
}
void technician::displayStatus()
Y1 b(3,4),*bp=&b;
Z1 c(5,6),*cp=&c;
X1 *p[2]={&b,&c};
for(int i=0;i<2;i++)
p[i]->output();
虚函数部分习题
Class Mammal
{
Public:
(1)void Speak(){cout<<”This is a Mammal!”<<endl;}
};
Class Dog:public Mammal
{
Public:
void Speak(){cout<<”this is a Dog!”<<endl;}
{
B b,*pb=&b;
A a,*pa=&a;
void (A::*paf1)()=A::f1;
void (A::*paf2)()=A::f2;
void (B::*pbf1)()=B::f1;
void (B::*pbf2)()=B::f2;
(pa->*paf1)();
pa=&b;
(pa->*paf1)();
pa->print(); pb->print();
delete pa;
}
5.下列程序中声明一个Mammal类,再由此派生出Dog类,二者都定义Speak()成员函数,基类中定义Speak()为虚函数。主程序中分别声明一个Mammal类和Dog类的对象,再分别 用对象名.函数名和指针的形式调用Speak()函数。请填空完成程序,并上机运行验证。
{
protected:
int k;
public:
XX ( int n = 5 ) : k (n){ }
~XX ( )
{cout<<“XX”;}
virtual void f ( ) ;
};
void XX :: f ( )
最新《C++程序设计案例教程》习题答案第9章 多态性和虚函数的使用
第9章多态性和虚函数的使用一、选择题1.C. 2.C 3.A 4.C 5. 6.D二、程序题(略)三、简答题1.C++多态性主要体现在哪两个方面?答:在C++中,多态性是指系统调用同名的函数,实现不同的功能。
多态性包含静态多态性和动态多态性。
静态多态性体现在编译时函数重载或者运算符重载上;展现了同一类中多个同名函数的处理机制。
而动态多态性是指程序运行过程中通过虚函数动态地确定针对的对象,展现继承层次结构中同名函数的处理机制。
2. 比较函数重载和虚函数在概念上和使用方式有什么区别。
函数重载是指函数名称相同,但是参数的个数或者参数的数据类型不同。
因此,系统调用重载函数时,会依据参数确定调用哪一个。
而在继承的机制中,基类的成员函数可能会与派生类新增的成员函数同名,包括参数个数和参数类型,这种现象不属于函数重载。
当基类的一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。
派生类可以对虚函数重新定义。
虚函数实现动态多态的问题。
3.比较抽象类、虚函数、纯虚函数的概念和使用上的区别。
虚函数通常在基类中定义,定义可以是空,派生类中可以对虚函数重写,也可以不写。
虚函数起到了接口的默认行为作用。
纯虚函数在基类中是没有定义的,必须在直接或者间接派生类中加以实现,它起到了接口的作用。
包含了纯虚函数的类,被称为抽象类。
抽象类不能建立对象。
4.谈谈虚基类和虚函数,区分两者不同的概念和各自的作用。
在继承机制中,一个派生类继承多个直接基类,而这些基类又有一个公共的基类,这个公共的基类成员在继承中可能产生多个拷贝。
虚基类的基本原则是在内存中只有基类成员的一份拷贝。
这样,通过把基类继承声明为虚拟的,就只能继承基类的一份拷贝,从而消除歧义。
用virtual限定符把基类继承说明为虚拟的。
虚函数指基类中成员函数声明为 virtual ,使它在一个或多个派生类中被重新定义,虚函数的作用是实现多态性。
虚函数必须是基类的非静态成员函数,其访问权限可以protected或public。
c多态性与虚函数习题
1.1C++支持两种多态性,分别是静态和动态。
1.2在编译时就确定的函数调用称为静态联编,它通过使用重载函数实现。
1.3在运行时才确定的函数调用称为动态联编,它通过虚函数来实现。
1.4虚函数的声明方法是在函数原型前加上关键字virtual。在基类中含有虚函数,在派生类中的函数没有显式写出virtual关键字,系统依据以下规则判断派生类的这个函数是否是虚函数:该函数是否和基类的虚函数参数个数相同 /同名;是否与基类的虚函数相应类型相同;是否与基类的虚函数返回值类型相同。如果满足上述3个条件,派生类的函数就是虚函数。并且该函数覆盖基类的虚函数。
A.可以说明虚函数
B.可以进行构造函数重载
C.可以定义友元函数
D.不能定义其对象
3.8类B是类A的公有派生类,类A和类B中都定义了虚函数func( ),p是一个指向类A对象的指针,则p->A::func( )将()。
A.调用类A中的函数func( )
B.调用类B中的函数func( )
C.根据p所指的对象类型而确定调用类A中或类B中的函数func( )
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;}
A.虚析构函数B.虚构造函数
C.纯虚函数D.静态成员函数
3.6以下基类中的成员函数,哪个表示纯虚函数(C)。
C++程序设计基础第6章 虚函数与多态性
6.2.1 虚函数的定义
2. 虚函数的定义 • 虚函数的定义是在基类中进行的 。 • 虚函数的定义语法格式如下:
virtual<函数类型><函数名>(形参表) {
函数体 }
12
6.2.1 虚函数的定义
3. 定义虚函数时,要注意遵循以下规则: 1)只有成员函数才能声明为虚函数,因为虚
函数仅适用于有继承关系的类对象,所以 普通函数不能声明为虚函数。 2)虚函数的声明只能出现在类声明中的函数 原型声明中,而不能出现在成员的函数体 实现上。 3)类的静态成员函数不可以定义为虚函数, 因为静态成员函数不受限于某个对象。
}
7
void main()
{
MaxClass mc(34,67,143,89);
cout<<"计算前两个数中的最大数为:“
<<mc.max(34,67)<<endl;
cout<<"计算前三个数中的最大数为:“
<<mc.max(34,67,143)<<endl;
cout<<"计算四个数中的最大数为:“
运行结果: 张晓强,园林工人 李文卓,生命科学教师
23
6.2.3 虚函数的重载
• 2. 多继承中的虚函数
【例6.8】多继承中使用虚函数例题。
#include <iostream.h>
class base1
//定义基类base1
{
public: virtual void display()
//函数定义为虚函数
运行结果:
(1) : 动物(食草/食肉). (2) : 食草动物 : 羚羊 (3) : 食草动物 : 羚羊 (4) : 食肉动物 : 老虎 (5) : 食肉动物 : 老虎 (6) : 食草动物 : 羚羊 (7) : 食肉动物 : 老虎
c++作业四
c++作业四第5章习题1. 什么是多态性?在C++中是如何实现多态的?答:多态是指同样的消息被不同类型的对象接收时导致完全不同的行为,是对类的特定成员函数的再抽象。
C++支持的多态有多种类型,重载(包括函数重载和运算符重载)和虚函数是其中主要的方式。
2. 虚函数与重载在设计方法上有何异同?答:重载函数要求函数有相同的返回值类型和函数名称,并有不同的参数序列;而虚函数则要求这三项完全相同;重载函数可以是成员函数或友员函数,而虚函数只能是成员函数;重载函数的调用是以所传递参数序列的差别作为调用不同函数的依据;虚函数是根据对象的不同去调用不同类的虚函数;重载函数则在编译时表现出多态性而虚函数在运行时表现出多态功能,这是C++的精髓;3. 编写一个时间类,实现时间的加、减、读和输出。
答:#includeclass Timepublic:Time(int a=0,int b=0,int c=0); void SetTime();void Display();Time operator + (Time &a); Time operator - (Time &a); private:int hour,minute,second;};Time::Time(int a,int b,int c) {hour=a;minute=b;second=c;}void Time::SetTime(){hour=10;minute=15;second=23;}void Time::Display()cout<<hour<<":"<<minute<<":"<<second<<=""> Time Time::operator + (Time &a){int x,y,z;x=hour+a.hour;y=minute+a.minute;z=second+a.second;return(Time(x,y,z));}Time Time::operator - (Time &a){int x,y,z;x=hour-a.hour;y=minute-a.minute;z=second-a.second;return(Time(x,y,z));}void main(){Time a,b,c;a.SetTime();b.SetTime();cout<<"A的时间为:";a.Display();cout<<"B的时间为:";b.Display();cout<<"c=a+b=";c=a+b;c.Display();cout<<"c=a-b=";c=a-b;c.Display();}运行结果是:A的时间为:10:15:23B的时间为:10:15:23C=a+b=20:30:46C=a-b=0:0:04. 定义一个哺乳动物Mammal类,再由此派生出狗Dog 类和牛类,三者都定义Speak成员函数,基类中定义为虚函数,定义一个Dog类的对象,调用Speak函数,观察运行结果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
作业题
一、写出下列程序运行结果
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( )。
5.5某学校对教师每月工资的计算公式如下:固定工资+课时补贴。
教授的固定工资为5000元,每个课时补贴50元;副教授的固定工资为3000元,每个课时补贴30元;讲师的固定工资为2000元,每个课时补贴20元。
给出教师抽象类及主函数,补充编写程序求若干教师的月工资。
#include<iostream>
using namespace std;
class Teacher{
protected:
double salary;
int workhours;
public:
Teacher(int wh=0){workhours=wh;}
virtual void cal_salary()=0;
void print(){cout<<salary<<endl;}
};
int main(){
Teacher *pt;
Prof prof(200);
pt=&prof;
pt->cal_salary();
prof.print();
Vice_Prof vice_prof(250);
pt=&vice_prof;
pt->cal_salary();
vice_prof.print();
Lecture lecture(100);
pt=&lecture;
pt->cal_salary();
lecture.print ();
return 0;
}。