首页 理论教育C++程序设计教程:实现多态性的方法

C++程序设计教程:实现多态性的方法

【摘要】:虚函数总是在派生环境中使用,用虚函数实现动态多态性的一般步骤如下:在基类中定义虚函数;在派生类中定义与基类虚函数同名、同参数、同返回类型的成员函数,即派生类中的虚函数。分析以下程序的执行结果。图7.18类层次类BaseA包括虚函数bf(),类BaseB包括非虚函数bf(),类Derived是从类BaseA和类BaseB派生的,其中也包括函数bf()。解:设计的类层次如图7.2所示,普通函数printobject()采用动态绑定的方法。

虚函数总是在派生环境中使用,用虚函数实现动态多态性的一般步骤如下:

(1)在基类中定义虚函数;

(2)在派生类中定义与基类虚函数同名、同参数、同返回类型的成员函数,即派生类中的虚函数。虽然基类中的虚函数与各派生类中虚函数同名、同参数,但由于各虚函数的函数体不同,因而可用同名虚函数在运行时完成对不同对象的操作,从而实现动态绑定。

(3)调用虚函数,其步骤如下:

①用基类定义指针变量,如,基类*ptr;

②将基类对象地址或派生类对象地址赋给该指针变量。如,ptr=&基类对象;或者ptr=&派生类对象;

③用“指针变量->虚函数(实参)”方式去调用基类或派生类中的虚函数,如,ptr->虚函数(实参)。

【例7.2】分析以下程序的执行结果。

解:上述程序中,各类之间构成的类层次如图7.1所示。

图7.1 8类层次

类BaseA包括虚函数bf(),类BaseB包括非虚函数bf(),类Derived是从类BaseA和类BaseB派生的,其中也包括函数bf()。那么类Derived中函数bf()是虚函数还是非虚函数呢?实际上,它在不同的场合呈现不同的性质:若相对于类BaseA的派生路径,由于类BaseA中的bf()为虚函数,所以它是一个虚函数;若相对于类BaseB的派生路径,由于类BaseB中的bf()为非虚函数,所以此时它是一般的重载函数。程序的执行结果如下:

class BaseA

class BaseB

class Derived

class BaseB

【例7.3】设有一个作品类Art,包括作者姓名、作品名字和作品年代等私有数据成员以及输出虚函数disp()。从Art类派生出一个绘画类Paint和一个音乐类Music,在Paint类中添加高度和宽度数据成员,在Music类中添加曲调数据成员,它们都实现了虚函数display()。再由Music类派生出室内曲Chamber类,其中添加了其他曲数数据成员,并实现了虚函数display()。要求编写一个普通函数printobject()输出所有这些类的对象。

解:设计的类层次如图7.2所示,普通函数printobject()采用动态绑定的方法。因为display()设计成虚函数,所以printobject()函数使用Art&d参数。

图7.2 类层次

程序如下:(www.chuimin.cn)

本程序的执行结果如下:

输出结果:

作者:贝多芬

名字:第9交响曲

年份:1824

类型:音乐

曲调:D小调

作者:达芬奇

名字:蒙娜丽莎

年份:1503

类型:绘画

尺寸:宽度=24,高度=36

作者:莫扎特

名字:费加罗的婚礼

年份:1786

类型:音乐

曲调:D大调

其他:室内乐4首