《第7章 多态性与虚函数》由会员分享,可在线阅读,更多相关《第7章 多态性与虚函数(27页珍藏版)》请在金锄头文库上搜索。
1、第七章第七章 多态性与虚函数多态性与虚函数 本章内容本章内容v多态性概述多态性概述v运算符重载运算符重载v虚函数虚函数教学目标教学目标v了解多态性的概念了解多态性的概念v掌握简单运算符重载的方法掌握简单运算符重载的方法v掌握虚函数的定义和使用方法掌握虚函数的定义和使用方法7.1 7.1 多态性多态性概述概述1. 多态性的含义多态性的含义在在C+C+中多态表现为同一形式的函数调用,中多态表现为同一形式的函数调用,可能调用不同的函数实现。可能调用不同的函数实现。2. 多态性的表现形式多态性的表现形式参数多态:函数模板和类模板参数多态:函数模板和类模板包含多态:继承了虚函数的派生类同名函数包含多态:
2、继承了虚函数的派生类同名函数重载多态:重载多态:函数重载函数重载和运算符重载和运算符重载强制多态:强制类型转换强制多态:强制类型转换7.2 7.2 运算符重载运算符重载1.1.运算符函数运算符函数l C+C+将各种运算符都处理成一个将各种运算符都处理成一个特殊的函数特殊的函数调用。调用。 例:在程序中写:例:在程序中写: 3+53+5 系统处理成:系统处理成:operatoroperator+ +(3 3,5 5););l C+C+中预定义的多数运算符函数其运算对象只能是基本数中预定义的多数运算符函数其运算对象只能是基本数据类型,而不适用于用户自定义类型(如类)据类型,而不适用于用户自定义类型
3、(如类)2.2.运算符重载运算符重载 对对C+C+的的运算符运算符函数进行函数进行重新定义重新定义,使之以同样的形式,使之以同样的形式按重新定义的方式操作按重新定义的方式操作类的对象类的对象。7.2 7.2 运算符重载运算符重载3.3.运算符重载的规则运算符重载的规则 7.2 7.2 运算符重载运算符重载4.4.实现运算符重载的实现运算符重载的两种方法两种方法将运算符函数重载为类的成员函数将运算符函数重载为类的成员函数将运算符函数重载为类的友元函数将运算符函数重载为类的友元函数7.2 7.2 运算符重载运算符重载说明:说明:F调用该函数的对象做为运算符函数的第一个参数调用该函数的对象做为运算符
4、函数的第一个参数F重载二元运算符时,参数表中应有一个形参。重载二元运算符时,参数表中应有一个形参。F重载一元运算符时,参数表应为空(后置重载一元运算符时,参数表应为空(后置+、-除外)。除外)。1)将运算符重载为类的成员函数)将运算符重载为类的成员函数class 类名类名 . 类型名类型名 operator运算符运算符(形参表形参表); .;类型名类型名 类名类名: operatoroperator运算符运算符( (形参表形参表)函数体函数体 例:例:用成员函数重载用成员函数重载“+”、“-” ,实现两个复数的加、减运,实现两个复数的加、减运算算 7.2 7.2 运算符重载运算符重载2 2)运
5、算符函数重载为类的友员函数)运算符函数重载为类的友员函数 在类体内说明:在类体内说明: friend 类型名类型名 operator 运算符(参数表)运算符(参数表);在类体外定义运算符函数的一般形式:在类体外定义运算符函数的一般形式: 类型名类型名 operator 运算符(参数表)运算符(参数表)F重载二元运算符时,参数表中应有两个形参。重载二元运算符时,参数表中应有两个形参。 重载一元运算符时,参数表应有一个形参。重载一元运算符时,参数表应有一个形参。 以下运算符不能重载为友元函数以下运算符不能重载为友元函数:=、( )、 、 - 但可以重载为成员函数但可以重载为成员函数说明:说明:例例
6、1:用友员函数重载用友员函数重载“+”、“-” ,实现两个复数的加、减运,实现两个复数的加、减运算算 讨论:讨论: 一元运算符、二元复合赋值运算符(如:一元运算符、二元复合赋值运算符(如:+=+=、-=-=)常常被重)常常被重载为成员函数;其他二元运算符常常被重载为友元函数。载为成员函数;其他二元运算符常常被重载为友元函数。在有些情况下,二元运算符不便于重载为成员函数。在有些情况下,二元运算符不便于重载为成员函数。 例例: 5.67+c 其中,其中,c是类是类complex的的一个对象。将一个对象。将“+”重载为友元重载为友元函数时,表达式将被函数时,表达式将被编译程序编译程序解释为:解释为:
7、 operator +(complex (5.67),c) /正确正确 (在(在complex类中应定义了相应的构造函数)。类中应定义了相应的构造函数)。 “+”重载为成员函数时,则表达式被解释为:重载为成员函数时,则表达式被解释为: 5.67.operator +(c) /错误错误例例7.13: 编写程序对字符串类重载编写程序对字符串类重载“+=运算符和运算符和=运算符实运算符实现两个字符串的连接。现两个字符串的连接。7.3 7.3 虚函数虚函数主要内容:主要内容:什么是虚函数什么是虚函数虚函数的作用虚函数的作用虚函数的定义和使用规则虚函数的定义和使用规则纯虚函数和抽象类简介纯虚函数和抽象类
8、简介 l静态多态性静态多态性 可在编译期间确定的多态性。通可在编译期间确定的多态性。通 常称为常称为静态联编静态联编(static binding)。重载多态重载多态和和参数多态参数多态一般是静态一般是静态多态的。多态的。l动态多态性动态多态性 在程序运行过程中,才能确定的多态性。通常称为在程序运行过程中,才能确定的多态性。通常称为动态联编动态联编(dynamic binding)。包含多态包含多态和和强制多态强制多态一一般是动态联编的。般是动态联编的。多态性的两种实现机制多态性的两种实现机制#include class Base int x;public : Base(int x1)x=x1
9、; void print( )cout“x=”x“ ”; ;class Derevid : public Base int y;public : Derevid(int x1,int y1):Base(x1)y=y1; void print( )Base:print();cout“y=”y print(); /调用哪个调用哪个print函数函数? pa=&d; pa-print(); /调用哪个调用哪个print函数函数?1.1.虚函数的引入虚函数的引入: :不用不用虚函数时的静态联编虚函数时的静态联编 输出结果:输出结果:x=5x=5 x=10 x=1017#include class Ba
10、se int x;public : Base(int x1)x=x1; virtual void print( )cout“x=”x“ ”; ;class Derevid : public Base int y;public : Derevid(int x1,int y1):Base(x1)y=y1; void print( )Base:print();cout“y=”y print(); /调用哪个调用哪个print函数函数? pa=&d; pa-print(); /调用哪个调用哪个print函数函数?1.1.虚函数的引入虚函数的引入 : :通过虚函数实现动态多态性通过虚函数实现动态多态性
11、输出结果:输出结果:X=5 x=10 y=20X=5 x=10 y=20187.3 7.3 虚函数虚函数2.2.虚函数虚函数虚函数是类的虚函数是类的非静态非静态成员函数。成员函数。一个成员函数被说明为虚函数后,表示它在派生类中可能一个成员函数被说明为虚函数后,表示它在派生类中可能有多种不同的实现。有多种不同的实现。3.3.虚函数的作用虚函数的作用与赋值兼容性结合实现动态多态性。与赋值兼容性结合实现动态多态性。4.4.定义虚函数的一般格式(在类体中)定义虚函数的一般格式(在类体中) virtual 类型名类型名 成员函数名(形参表)成员函数名(形参表) 或:或: virtual 类型名类型名 成
12、员函数名(形参表);成员函数名(形参表); 类的一个成员函数被说明或定义为虚函数后,由该类派类的一个成员函数被说明或定义为虚函数后,由该类派生的类中所有与虚函数函数头相同的函数均为虚函数。生的类中所有与虚函数函数头相同的函数均为虚函数。7.3 7.3 虚函数虚函数5.5.虚函数的使用规则虚函数的使用规则虚函数用于继承和派生,在基类中定义。虚函数用于继承和派生,在基类中定义。基类的虚函数在派生类中有多种实现,但函数原基类的虚函数在派生类中有多种实现,但函数原型应保持一致,否则为静态联编。型应保持一致,否则为静态联编。只能通过基类的指针或引用访问派生类对象来实只能通过基类的指针或引用访问派生类对象
13、来实现动态联编现动态联编构造函数构造函数不能是不能是虚函数虚函数析构函数可以是虚函数,说明形式为:析构函数可以是虚函数,说明形式为:virtual 类类名()名() 例例7-8:不使用虚函数的静态联编示例。不使用虚函数的静态联编示例。 运行程序后,输出的面积均为运行程序后,输出的面积均为0。例例7-97-9:通过虚函数实现动态多态性通过虚函数实现动态多态性 运行程序后,可以正确输出各形状的面积。运行程序后,可以正确输出各形状的面积。例例7-10: 虚析构函数使用示例。虚析构函数使用示例。 7.3 7.3 虚函数虚函数6.6.纯虚函数与抽象类纯虚函数与抽象类 n纯虚函数纯虚函数:如果无法或无需定
14、义基类的虚函数:如果无法或无需定义基类的虚函数的函数体,可将该虚函数定义为纯虚函数,的函数体,可将该虚函数定义为纯虚函数,形式形式为:为:virtual virtual 类型名类型名 函数名(形参表)函数名(形参表)=0;=0;n抽象类:抽象类: 带纯虚函数的类带纯虚函数的类n使用规则使用规则:F抽象类只能作为其他类的基类抽象类只能作为其他类的基类F不能定义抽象类的对象,但可以定义它的指不能定义抽象类的对象,但可以定义它的指针或引用。针或引用。例:例:纯虚函数和抽象类示例纯虚函数和抽象类示例 shape(抽象类)Point(点类)Circle(圆类)Sphere(球体类)例:例:纯虚函数和抽象类示例纯虚函数和抽象类示例