【大学课件】C面向对象程序设计 多态性与虚函数

上传人:汽*** 文档编号:568656831 上传时间:2024-07-25 格式:PPT 页数:25 大小:101KB
返回 下载 相关 举报
【大学课件】C面向对象程序设计 多态性与虚函数_第1页
第1页 / 共25页
【大学课件】C面向对象程序设计 多态性与虚函数_第2页
第2页 / 共25页
【大学课件】C面向对象程序设计 多态性与虚函数_第3页
第3页 / 共25页
【大学课件】C面向对象程序设计 多态性与虚函数_第4页
第4页 / 共25页
【大学课件】C面向对象程序设计 多态性与虚函数_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《【大学课件】C面向对象程序设计 多态性与虚函数》由会员分享,可在线阅读,更多相关《【大学课件】C面向对象程序设计 多态性与虚函数(25页珍藏版)》请在金锄头文库上搜索。

1、1C+面向对象程序设计第九章 多态性与虚函数http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系2学习目标理解多态性和虚函数的概念理解多态性和虚函数的概念理解多态性和虚函数的概念理解多态性和虚函数的概念了解静态多态性和动态多态性了解静态多态性和动态多态性了解静态多态性和动态多态性了解静态多态性和动态多态性掌握虚函数的定义和调用方法掌握虚函数的定义和调用方法掌握虚函数的定义和调用方法掌握虚函数的定义和调用方法掌握多态性的实现方法以及虚函数在其实现中起掌握多态性的实现方法以及虚函数在其实现中起掌握多态性的实现方法以及虚函数在其实现中起掌握

2、多态性的实现方法以及虚函数在其实现中起到的作用到的作用到的作用到的作用掌握纯虚函数和抽象类的概念及应用掌握纯虚函数和抽象类的概念及应用掌握纯虚函数和抽象类的概念及应用掌握纯虚函数和抽象类的概念及应用http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系39.1 为什么需要多态性n n前面章节讲述了面向对象程序设计的重要机制:数据抽象、封装和继前面章节讲述了面向对象程序设计的重要机制:数据抽象、封装和继前面章节讲述了面向对象程序设计的重要机制:数据抽象、封装和继前面章节讲述了面向对象程序设计的重要机制:数据抽象、封装和继承,多态性也是面向

3、对象的重要特征之一。若语言不支持多态,则不承,多态性也是面向对象的重要特征之一。若语言不支持多态,则不承,多态性也是面向对象的重要特征之一。若语言不支持多态,则不承,多态性也是面向对象的重要特征之一。若语言不支持多态,则不能称为面向对象的。只支持类而不支持多态,只能称为基于对象的,能称为面向对象的。只支持类而不支持多态,只能称为基于对象的,能称为面向对象的。只支持类而不支持多态,只能称为基于对象的,能称为面向对象的。只支持类而不支持多态,只能称为基于对象的,如如如如AdaAdaAdaAda,VBVBVBVB等。多态性的应用,使面向对象编程技术比较容易处理各等。多态性的应用,使面向对象编程技术比

4、较容易处理各等。多态性的应用,使面向对象编程技术比较容易处理各等。多态性的应用,使面向对象编程技术比较容易处理各种对象之间的相互作用;可以使编程显得更为简捷、便利,易于对程种对象之间的相互作用;可以使编程显得更为简捷、便利,易于对程种对象之间的相互作用;可以使编程显得更为简捷、便利,易于对程种对象之间的相互作用;可以使编程显得更为简捷、便利,易于对程序进行开发和扩展,它为程序的模块化设计提供了又一手段。序进行开发和扩展,它为程序的模块化设计提供了又一手段。序进行开发和扩展,它为程序的模块化设计提供了又一手段。序进行开发和扩展,它为程序的模块化设计提供了又一手段。n n在进行面向对象编程时,在进

5、行面向对象编程时,在进行面向对象编程时,在进行面向对象编程时,C+C+C+C+力求模仿客观世界的规律。多态性概念力求模仿客观世界的规律。多态性概念力求模仿客观世界的规律。多态性概念力求模仿客观世界的规律。多态性概念也是体现了现实社会中各个事物之间的联系和作用。对同一个消息,也是体现了现实社会中各个事物之间的联系和作用。对同一个消息,也是体现了现实社会中各个事物之间的联系和作用。对同一个消息,也是体现了现实社会中各个事物之间的联系和作用。对同一个消息,不同的对象会有不同的反应。比如一个经理要到外地出差,他会把这不同的对象会有不同的反应。比如一个经理要到外地出差,他会把这不同的对象会有不同的反应。

6、比如一个经理要到外地出差,他会把这不同的对象会有不同的反应。比如一个经理要到外地出差,他会把这个消息告诉他身边的人:他的妻子、秘书、下属;这些人听到这个消个消息告诉他身边的人:他的妻子、秘书、下属;这些人听到这个消个消息告诉他身边的人:他的妻子、秘书、下属;这些人听到这个消个消息告诉他身边的人:他的妻子、秘书、下属;这些人听到这个消息会有不同的反应:他的妻子会为他准备行李,下属会为他准备出差息会有不同的反应:他的妻子会为他准备行李,下属会为他准备出差息会有不同的反应:他的妻子会为他准备行李,下属会为他准备出差息会有不同的反应:他的妻子会为他准备行李,下属会为他准备出差的材料,秘书会为他安排车票

7、和住宿。这就体现了多态性。的材料,秘书会为他安排车票和住宿。这就体现了多态性。的材料,秘书会为他安排车票和住宿。这就体现了多态性。的材料,秘书会为他安排车票和住宿。这就体现了多态性。n n多态性的概念是同样的消息被类的不同对象接收时导致完全不同行为多态性的概念是同样的消息被类的不同对象接收时导致完全不同行为多态性的概念是同样的消息被类的不同对象接收时导致完全不同行为多态性的概念是同样的消息被类的不同对象接收时导致完全不同行为的一种现象。消息指对类的成员函数的调用。换句话说,每个不同的的一种现象。消息指对类的成员函数的调用。换句话说,每个不同的的一种现象。消息指对类的成员函数的调用。换句话说,每

8、个不同的的一种现象。消息指对类的成员函数的调用。换句话说,每个不同的对象可以以适合自己的方式去响应对同一个成员函数的调用。简单地对象可以以适合自己的方式去响应对同一个成员函数的调用。简单地对象可以以适合自己的方式去响应对同一个成员函数的调用。简单地对象可以以适合自己的方式去响应对同一个成员函数的调用。简单地讲,多态性就是一种实现讲,多态性就是一种实现讲,多态性就是一种实现讲,多态性就是一种实现“一种接口,多种方法一种接口,多种方法一种接口,多种方法一种接口,多种方法”的技术,是面向对的技术,是面向对的技术,是面向对的技术,是面向对象程序设计的重要特性。象程序设计的重要特性。象程序设计的重要特性

9、。象程序设计的重要特性。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系49.1.1 多态性的实现方法n n同一段代码,当用不同的对象去调用时,该代码具有不同的功能,这同一段代码,当用不同的对象去调用时,该代码具有不同的功能,这同一段代码,当用不同的对象去调用时,该代码具有不同的功能,这同一段代码,当用不同的对象去调用时,该代码具有不同的功能,这称为多态性。称为多态性。称为多态性。称为多态性。C+C+提供的多态性分为静态多态性(编译时多态)和动提供的多态性分为静态多态性(编译时多态)和动提供的多态性分为静态多态性(编译时多态)和动

10、提供的多态性分为静态多态性(编译时多态)和动态多态性(运行时多态)。静态多态性是一种编译时的多态,是通过态多态性(运行时多态)。静态多态性是一种编译时的多态,是通过态多态性(运行时多态)。静态多态性是一种编译时的多态,是通过态多态性(运行时多态)。静态多态性是一种编译时的多态,是通过重载和模板实现的。动态多态性是一种运行时的多态,其基础是数据重载和模板实现的。动态多态性是一种运行时的多态,其基础是数据重载和模板实现的。动态多态性是一种运行时的多态,其基础是数据重载和模板实现的。动态多态性是一种运行时的多态,其基础是数据封装和继承机制,通过继承建立类层次,并通过在基类中定义虚函数封装和继承机制,

11、通过继承建立类层次,并通过在基类中定义虚函数封装和继承机制,通过继承建立类层次,并通过在基类中定义虚函数封装和继承机制,通过继承建立类层次,并通过在基类中定义虚函数来实现多态性,即在基类和派生类中建立同名的函数,但是函数的功来实现多态性,即在基类和派生类中建立同名的函数,但是函数的功来实现多态性,即在基类和派生类中建立同名的函数,但是函数的功来实现多态性,即在基类和派生类中建立同名的函数,但是函数的功能是不同的。能是不同的。能是不同的。能是不同的。n n函数重载实现多态:对同一个函数名,当用不同的实参调用时,会函数重载实现多态:对同一个函数名,当用不同的实参调用时,会函数重载实现多态:对同一个

12、函数名,当用不同的实参调用时,会函数重载实现多态:对同一个函数名,当用不同的实参调用时,会调用到不同的重载函数版本,因而完成不同的功能,这是一种多态性调用到不同的重载函数版本,因而完成不同的功能,这是一种多态性调用到不同的重载函数版本,因而完成不同的功能,这是一种多态性调用到不同的重载函数版本,因而完成不同的功能,这是一种多态性的体现。的体现。的体现。的体现。n n模板实现多态:模板是一类函数或类的样板,通过用不同的模板实模板实现多态:模板是一类函数或类的样板,通过用不同的模板实模板实现多态:模板是一类函数或类的样板,通过用不同的模板实模板实现多态:模板是一类函数或类的样板,通过用不同的模板实

13、参调用模板,同一个名字可生成不同的具体函数或具体类,从而实现参调用模板,同一个名字可生成不同的具体函数或具体类,从而实现参调用模板,同一个名字可生成不同的具体函数或具体类,从而实现参调用模板,同一个名字可生成不同的具体函数或具体类,从而实现不同的功能,这也是一种多态性的体现。不同的功能,这也是一种多态性的体现。不同的功能,这也是一种多态性的体现。不同的功能,这也是一种多态性的体现。n n虚函数实现多态:通过动态束定机制,使相同的函数调用代码可能虚函数实现多态:通过动态束定机制,使相同的函数调用代码可能虚函数实现多态:通过动态束定机制,使相同的函数调用代码可能虚函数实现多态:通过动态束定机制,使

14、相同的函数调用代码可能调用不同的类(基类或派生类)的虚函数,从而完成不同的功能,这调用不同的类(基类或派生类)的虚函数,从而完成不同的功能,这调用不同的类(基类或派生类)的虚函数,从而完成不同的功能,这调用不同的类(基类或派生类)的虚函数,从而完成不同的功能,这又是一种多态性的体现。又是一种多态性的体现。又是一种多态性的体现。又是一种多态性的体现。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系59.1.2 静态多态性和动态多态性编译时多态通过静态联编实现,运行时多态通过动态联编译时多态通过静态联编实现,运行时多态通过动态联编译时

15、多态通过静态联编实现,运行时多态通过动态联编译时多态通过静态联编实现,运行时多态通过动态联编实现。编实现。编实现。编实现。1 1 联编联编联编联编在面向对象程序设计中,联编(在面向对象程序设计中,联编(在面向对象程序设计中,联编(在面向对象程序设计中,联编(bindingbinding)的含义是把)的含义是把)的含义是把)的含义是把一个函数名与其实现的代码联系在一起,即主调函数代码一个函数名与其实现的代码联系在一起,即主调函数代码一个函数名与其实现的代码联系在一起,即主调函数代码一个函数名与其实现的代码联系在一起,即主调函数代码必须与被调函数代码连接起来。必须与被调函数代码连接起来。必须与被调

16、函数代码连接起来。必须与被调函数代码连接起来。按照联编所在的阶段,联编分为静态联编按照联编所在的阶段,联编分为静态联编按照联编所在的阶段,联编分为静态联编按照联编所在的阶段,联编分为静态联编(static (static binding) binding) 和动态联编和动态联编和动态联编和动态联编(dynamic binding)(dynamic binding)。n n静态联编又称先期联编静态联编又称先期联编静态联编又称先期联编静态联编又称先期联编(early binding)(early binding),是在编译时进行的,是在编译时进行的,是在编译时进行的,是在编译时进行的,即是在编译阶

17、段就必须确定函数名与代码间的对应关系。即是在编译阶段就必须确定函数名与代码间的对应关系。即是在编译阶段就必须确定函数名与代码间的对应关系。即是在编译阶段就必须确定函数名与代码间的对应关系。换句话说,主调函数和被调代码的关系早在编译时就确定换句话说,主调函数和被调代码的关系早在编译时就确定换句话说,主调函数和被调代码的关系早在编译时就确定换句话说,主调函数和被调代码的关系早在编译时就确定了。了。了。了。n n动态联编又称迟后联编动态联编又称迟后联编动态联编又称迟后联编动态联编又称迟后联编(late binding)(late binding),是在程序运行过程,是在程序运行过程,是在程序运行过程

18、,是在程序运行过程中根据程序运行时的需要进行的。根据对象的不同来决定中根据程序运行时的需要进行的。根据对象的不同来决定中根据程序运行时的需要进行的。根据对象的不同来决定中根据程序运行时的需要进行的。根据对象的不同来决定调用哪个(成员)函数进行联编。在编译阶段,系统还不调用哪个(成员)函数进行联编。在编译阶段,系统还不调用哪个(成员)函数进行联编。在编译阶段,系统还不调用哪个(成员)函数进行联编。在编译阶段,系统还不能确定两者的对应关系。动态多态性是与动态联编相联系能确定两者的对应关系。动态多态性是与动态联编相联系能确定两者的对应关系。动态多态性是与动态联编相联系能确定两者的对应关系。动态多态性

19、是与动态联编相联系的。的。的。的。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系6n n静态联编的最大优点是速度快,运行时的开销仅仅是传递静态联编的最大优点是速度快,运行时的开销仅仅是传递静态联编的最大优点是速度快,运行时的开销仅仅是传递静态联编的最大优点是速度快,运行时的开销仅仅是传递参数、执行函数调用、清除栈等。不过,程序员必须预测参数、执行函数调用、清除栈等。不过,程序员必须预测参数、执行函数调用、清除栈等。不过,程序员必须预测参数、执行函数调用、清除栈等。不过,程序员必须预测在每一种情况下,在所有的函数调用中,将要使用哪

20、些对在每一种情况下,在所有的函数调用中,将要使用哪些对在每一种情况下,在所有的函数调用中,将要使用哪些对在每一种情况下,在所有的函数调用中,将要使用哪些对象。这不仅具有局限性,有时也是不可能的。象。这不仅具有局限性,有时也是不可能的。象。这不仅具有局限性,有时也是不可能的。象。这不仅具有局限性,有时也是不可能的。n n动态联编的问题显然是执行效率。这必须由代码本身在运动态联编的问题显然是执行效率。这必须由代码本身在运动态联编的问题显然是执行效率。这必须由代码本身在运动态联编的问题显然是执行效率。这必须由代码本身在运行时刻推测调用哪个函数,然后再调用它。有些语言,如行时刻推测调用哪个函数,然后再

21、调用它。有些语言,如行时刻推测调用哪个函数,然后再调用它。有些语言,如行时刻推测调用哪个函数,然后再调用它。有些语言,如SmalltalkSmalltalk,仅使用动态联编。仅用动态联编大大加强了语,仅使用动态联编。仅用动态联编大大加强了语,仅使用动态联编。仅用动态联编大大加强了语,仅使用动态联编。仅用动态联编大大加强了语言的功能,但速度浪费也很严重。言的功能,但速度浪费也很严重。言的功能,但速度浪费也很严重。言的功能,但速度浪费也很严重。ANSI CANSI C只使用静态联只使用静态联只使用静态联只使用静态联编,结果是速度快但灵活性不够。编,结果是速度快但灵活性不够。编,结果是速度快但灵活性

22、不够。编,结果是速度快但灵活性不够。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系72 2 2 2 静态多态性静态多态性静态多态性静态多态性n n在没有类层次的场合,使用函数重载的方式实现静态多态性。在没有类层次的场合,使用函数重载的方式实现静态多态性。在没有类层次的场合,使用函数重载的方式实现静态多态性。在没有类层次的场合,使用函数重载的方式实现静态多态性。各个重载函数名称相同,但参数表应在参数个数、类型和次序各个重载函数名称相同,但参数表应在参数个数、类型和次序各个重载函数名称相同,但参数表应在参数个数、类型和次序各个重载函

23、数名称相同,但参数表应在参数个数、类型和次序上有所不同。编译器根据参数表来识别各个重载函数。根据参上有所不同。编译器根据参数表来识别各个重载函数。根据参上有所不同。编译器根据参数表来识别各个重载函数。根据参上有所不同。编译器根据参数表来识别各个重载函数。根据参数表,系统在编译时就完成静态联编的过程。关于没有类层次数表,系统在编译时就完成静态联编的过程。关于没有类层次数表,系统在编译时就完成静态联编的过程。关于没有类层次数表,系统在编译时就完成静态联编的过程。关于没有类层次的函数重载实现多态的例子前面已经介绍,这里不再赘述。的函数重载实现多态的例子前面已经介绍,这里不再赘述。的函数重载实现多态的

24、例子前面已经介绍,这里不再赘述。的函数重载实现多态的例子前面已经介绍,这里不再赘述。n n在建立了类层次的场合,各个类可以有名字和参数表相同的成在建立了类层次的场合,各个类可以有名字和参数表相同的成在建立了类层次的场合,各个类可以有名字和参数表相同的成在建立了类层次的场合,各个类可以有名字和参数表相同的成员函数。图员函数。图员函数。图员函数。图9.19.1显示出单继承建立的类层次。显示出单继承建立的类层次。显示出单继承建立的类层次。显示出单继承建立的类层次。StudentStudent类描述学类描述学类描述学类描述学生的特征。派生类生的特征。派生类生的特征。派生类生的特征。派生类Smallst

25、udentSmallstudent描述小学生特征。派生类中重描述小学生特征。派生类中重描述小学生特征。派生类中重描述小学生特征。派生类中重载了函数载了函数载了函数载了函数print()print()。每个类的成员函数。每个类的成员函数。每个类的成员函数。每个类的成员函数print()print()功能是显示相应对功能是显示相应对功能是显示相应对功能是显示相应对象的数据成员。我们想实现不同的对象调用象的数据成员。我们想实现不同的对象调用象的数据成员。我们想实现不同的对象调用象的数据成员。我们想实现不同的对象调用print()print()时,输出不时,输出不时,输出不时,输出不同的内容实现多态性

26、。但是,如果基类中的没有将函数同的内容实现多态性。但是,如果基类中的没有将函数同的内容实现多态性。但是,如果基类中的没有将函数同的内容实现多态性。但是,如果基类中的没有将函数print()print()定义为虚函数,那么,即使在类层次中该函数被重载(函数名定义为虚函数,那么,即使在类层次中该函数被重载(函数名定义为虚函数,那么,即使在类层次中该函数被重载(函数名定义为虚函数,那么,即使在类层次中该函数被重载(函数名字和参数表完全相同),仍然不可能实现任何多态性。在这种字和参数表完全相同),仍然不可能实现任何多态性。在这种字和参数表完全相同),仍然不可能实现任何多态性。在这种字和参数表完全相同)

27、,仍然不可能实现任何多态性。在这种场合,联编还是静态的。场合,联编还是静态的。场合,联编还是静态的。场合,联编还是静态的。Student类print()Smallstudent类print()http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系8【例【例9-29-2】派生类对象替换基类对象。】派生类对象替换基类对象。见教材见教材见教材见教材P114P114P114P114n n从运行结果可以看出,以上几种方式调用的都是基类的从运行结果可以看出,以上几种方式调用的都是基类的从运行结果可以看出,以上几种方式调用的都是基类的从运行结果可以看

28、出,以上几种方式调用的都是基类的SpeakSpeakSpeakSpeak()()()()函数。因而可以得到下列重要结论:不论哪一种情形,函数。因而可以得到下列重要结论:不论哪一种情形,函数。因而可以得到下列重要结论:不论哪一种情形,函数。因而可以得到下列重要结论:不论哪一种情形,派生类对象替换基类对象后,只能当作基类对象来使用。派生类对象替换基类对象后,只能当作基类对象来使用。派生类对象替换基类对象后,只能当作基类对象来使用。派生类对象替换基类对象后,只能当作基类对象来使用。不论派生类是否存在同名覆盖成员,这样的基类对象所访不论派生类是否存在同名覆盖成员,这样的基类对象所访不论派生类是否存在同

29、名覆盖成员,这样的基类对象所访不论派生类是否存在同名覆盖成员,这样的基类对象所访问的成员都只能来自基类。那么如何才能得到我们需要的问的成员都只能来自基类。那么如何才能得到我们需要的问的成员都只能来自基类。那么如何才能得到我们需要的问的成员都只能来自基类。那么如何才能得到我们需要的结果呢(形成多态)?可以使用虚函数来实现动态联编。结果呢(形成多态)?可以使用虚函数来实现动态联编。结果呢(形成多态)?可以使用虚函数来实现动态联编。结果呢(形成多态)?可以使用虚函数来实现动态联编。 http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系93

30、虚函数和动态多态性虚函数和动态多态性n n要获得多态性的对象,必须建立一个类等级。在建立了类要获得多态性的对象,必须建立一个类等级。在建立了类要获得多态性的对象,必须建立一个类等级。在建立了类要获得多态性的对象,必须建立一个类等级。在建立了类层次后,实现动态多态性的方法是在基类中定义虚函数层次后,实现动态多态性的方法是在基类中定义虚函数层次后,实现动态多态性的方法是在基类中定义虚函数层次后,实现动态多态性的方法是在基类中定义虚函数 (virtual functions) (virtual functions) (virtual functions) (virtual functions) 。虚

31、函数的声明方法是在基类中的。虚函数的声明方法是在基类中的。虚函数的声明方法是在基类中的。虚函数的声明方法是在基类中的成员函数前用关键字成员函数前用关键字成员函数前用关键字成员函数前用关键字virtualvirtualvirtualvirtual说明,在派生类中,重载的说明,在派生类中,重载的说明,在派生类中,重载的说明,在派生类中,重载的虚函数名之前可略去关键字虚函数名之前可略去关键字虚函数名之前可略去关键字虚函数名之前可略去关键字virtualvirtualvirtualvirtual。其原型格式如下:。其原型格式如下:。其原型格式如下:。其原型格式如下:n nvirtual virtual

32、 virtual virtual 函数返回类型函数返回类型函数返回类型函数返回类型 函数名函数名函数名函数名( ( ( ( 参数表参数表参数表参数表 ); ); ); );n n虚函数存在于继承关系中,当一个类的成员函数声明为虚虚函数存在于继承关系中,当一个类的成员函数声明为虚虚函数存在于继承关系中,当一个类的成员函数声明为虚虚函数存在于继承关系中,当一个类的成员函数声明为虚函数后,在该类的直接或间接的派生类中就可以定义与该函数后,在该类的直接或间接的派生类中就可以定义与该函数后,在该类的直接或间接的派生类中就可以定义与该函数后,在该类的直接或间接的派生类中就可以定义与该基类中虚函数相同的函数

33、(函数返回类型、函数名和参数基类中虚函数相同的函数(函数返回类型、函数名和参数基类中虚函数相同的函数(函数返回类型、函数名和参数基类中虚函数相同的函数(函数返回类型、函数名和参数表完全相同,但函数体不同。注意与函数的重载不同)。表完全相同,但函数体不同。注意与函数的重载不同)。表完全相同,但函数体不同。注意与函数的重载不同)。表完全相同,但函数体不同。注意与函数的重载不同)。当编译器看见虚函数时,就会实行动态联编。因此当用基当编译器看见虚函数时,就会实行动态联编。因此当用基当编译器看见虚函数时,就会实行动态联编。因此当用基当编译器看见虚函数时,就会实行动态联编。因此当用基类指针指向带有虚函数的

34、基类的派生类对象时,系统会自类指针指向带有虚函数的基类的派生类对象时,系统会自类指针指向带有虚函数的基类的派生类对象时,系统会自类指针指向带有虚函数的基类的派生类对象时,系统会自动用派生类中的同名函数去代替基类中的虚函数,这个过动用派生类中的同名函数去代替基类中的虚函数,这个过动用派生类中的同名函数去代替基类中的虚函数,这个过动用派生类中的同名函数去代替基类中的虚函数,这个过程称为覆盖(程称为覆盖(程称为覆盖(程称为覆盖(overridingoverridingoverridingoverriding)。而对于非虚函数,编译器则)。而对于非虚函数,编译器则)。而对于非虚函数,编译器则)。而对于

35、非虚函数,编译器则会采用静态联编。会采用静态联编。会采用静态联编。会采用静态联编。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系10【例【例9-39-3】利用虚函数输出学生的不同的信息。】利用虚函数输出学生的不同的信息。n n见教材见教材见教材见教材P116P116P116P116n n区别在于:将基类区别在于:将基类区别在于:将基类区别在于:将基类StudentStudentStudentStudent中的成员函数中的成员函数中的成员函数中的成员函数print()print()print()print()定义为虚定义为虚定义为

36、虚定义为虚函数。在主函数函数。在主函数函数。在主函数函数。在主函数main()main()main()main()中,分别建立了中,分别建立了中,分别建立了中,分别建立了StudentStudentStudentStudent和和和和SmallstudentSmallstudentSmallstudentSmallstudent类的对象类的对象类的对象类的对象x, yx, yx, yx, y。ptptptpt是是是是StudentStudentStudentStudent类型指针。先类型指针。先类型指针。先类型指针。先使使使使ptptptpt指向基类的对象指向基类的对象指向基类的对象指向基类的

37、对象x x x x,并调用函数,并调用函数,并调用函数,并调用函数print()print()print()print(),然后用指针,然后用指针,然后用指针,然后用指针ptptptpt指向派生类对象指向派生类对象指向派生类对象指向派生类对象y y y y,然后调用成员函数,然后调用成员函数,然后调用成员函数,然后调用成员函数print()print()print()print(),由于基,由于基,由于基,由于基类中的类中的类中的类中的print()print()print()print()为虚函数,所以系统自动用派生类中的为虚函数,所以系统自动用派生类中的为虚函数,所以系统自动用派生类中的为

38、虚函数,所以系统自动用派生类中的printprintprintprint()()()()去代替(覆盖)基类中虚函数,从而实现多态性。去代替(覆盖)基类中虚函数,从而实现多态性。去代替(覆盖)基类中虚函数,从而实现多态性。去代替(覆盖)基类中虚函数,从而实现多态性。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系11StudentSmallStudentnumbernumber* name* nameVirtual print()Virtual print()numbernumber* name* nameVirtual print

39、()Virtual print()Virtual print()Virtual print()http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系12总的来说,取得动态多态性的过程是:总的来说,取得动态多态性的过程是:总的来说,取得动态多态性的过程是:总的来说,取得动态多态性的过程是:建立类层次建立类层次建立类层次建立类层次在基类中定义虚函数在基类中定义虚函数在基类中定义虚函数在基类中定义虚函数在派生类中重载那个虚函数在派生类中重载那个虚函数在派生类中重载那个虚函数在派生类中重载那个虚函数定义基类指针,使该指针指向所需的派生类对象定义

40、基类指针,使该指针指向所需的派生类对象定义基类指针,使该指针指向所需的派生类对象定义基类指针,使该指针指向所需的派生类对象动态多态性是通过建立类层次和在基类中定义虚函数来实动态多态性是通过建立类层次和在基类中定义虚函数来实动态多态性是通过建立类层次和在基类中定义虚函数来实动态多态性是通过建立类层次和在基类中定义虚函数来实现的。现的。现的。现的。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系139.2 对虚函数的限制9.2.1 9.2.1 声明虚函数的限制声明虚函数的限制声明虚函数的限制声明虚函数的限制一般情况下,可将类中具有共性

41、的成员函数声明为虚函数,而个一般情况下,可将类中具有共性的成员函数声明为虚函数,而个一般情况下,可将类中具有共性的成员函数声明为虚函数,而个一般情况下,可将类中具有共性的成员函数声明为虚函数,而个性的函数往往为某一个类独有,声明为一般成员函数。将类的成员函性的函数往往为某一个类独有,声明为一般成员函数。将类的成员函性的函数往往为某一个类独有,声明为一般成员函数。将类的成员函性的函数往往为某一个类独有,声明为一般成员函数。将类的成员函数声明为虚函数有利于编程,但下面的函数不能声明为虚函数:数声明为虚函数有利于编程,但下面的函数不能声明为虚函数:数声明为虚函数有利于编程,但下面的函数不能声明为虚函

42、数:数声明为虚函数有利于编程,但下面的函数不能声明为虚函数:构造函数不能声明为虚函数。构造函数在对象创建时调用,完成对象构造函数不能声明为虚函数。构造函数在对象创建时调用,完成对象构造函数不能声明为虚函数。构造函数在对象创建时调用,完成对象构造函数不能声明为虚函数。构造函数在对象创建时调用,完成对象的初始化,此时对象正在创建中,基类指针无从指向。只有在构造过的初始化,此时对象正在创建中,基类指针无从指向。只有在构造过的初始化,此时对象正在创建中,基类指针无从指向。只有在构造过的初始化,此时对象正在创建中,基类指针无从指向。只有在构造过程完成后,对象才存在,才能被基类指针指向。程完成后,对象才存

43、在,才能被基类指针指向。程完成后,对象才存在,才能被基类指针指向。程完成后,对象才存在,才能被基类指针指向。静态成员函数不能是虚函数。因为静态成员函数属于整个类的所有对静态成员函数不能是虚函数。因为静态成员函数属于整个类的所有对静态成员函数不能是虚函数。因为静态成员函数属于整个类的所有对静态成员函数不能是虚函数。因为静态成员函数属于整个类的所有对象,不受限于某个对象,没有多态性的特征。象,不受限于某个对象,没有多态性的特征。象,不受限于某个对象,没有多态性的特征。象,不受限于某个对象,没有多态性的特征。内联函数不能是虚函数。内联函数是在原地展开,其功能形式相当于内联函数不能是虚函数。内联函数是

44、在原地展开,其功能形式相当于内联函数不能是虚函数。内联函数是在原地展开,其功能形式相当于内联函数不能是虚函数。内联函数是在原地展开,其功能形式相当于将函数中的语句直接写到函数调用之处,不具有多态性的特征。在基将函数中的语句直接写到函数调用之处,不具有多态性的特征。在基将函数中的语句直接写到函数调用之处,不具有多态性的特征。在基将函数中的语句直接写到函数调用之处,不具有多态性的特征。在基类类体中,将某成员函数定义为虚函数,则编译器不会视该虚函数为类类体中,将某成员函数定义为虚函数,则编译器不会视该虚函数为类类体中,将某成员函数定义为虚函数,则编译器不会视该虚函数为类类体中,将某成员函数定义为虚函

45、数,则编译器不会视该虚函数为内联函数。即使用关键字内联函数。即使用关键字内联函数。即使用关键字内联函数。即使用关键字inlineinline说明它是内联函数,编译器也会把说明它是内联函数,编译器也会把说明它是内联函数,编译器也会把说明它是内联函数,编译器也会把它视作非内联函数。它视作非内联函数。它视作非内联函数。它视作非内联函数。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系14【例例9-49-4】声明虚函数的限制。声明虚函数的限制。见教材见教材见教材见教材P118P118程序运行结果:程序运行结果:程序运行结果:程序运行结果:

46、在基类中在基类中在基类中在基类中. Data = 10. Data = 10在基类中在基类中在基类中在基类中. Data = 20. Data = 20http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系159.2.2 9.2.2 虚函数的使用限制虚函数的使用限制【例【例【例【例9-59-5】虚函数实现多态性。】虚函数实现多态性。】虚函数实现多态性。】虚函数实现多态性。见教材见教材见教材见教材P119P119程序运行结果:程序运行结果:程序运行结果:程序运行结果:How does a pet speak ?How does a pet

47、 speak ?miao!miao!miao!miao!wang!wang!wang!wang!miao!miao!miao!miao!wang!wang!wang!wang!miao!miao!miao!miao!http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系16虚函数的使用限制:虚函数的使用限制:虚函数的使用限制:虚函数的使用限制:应通过指针或引用调用虚函数,而不要用对象名调用虚函应通过指针或引用调用虚函数,而不要用对象名调用虚函应通过指针或引用调用虚函数,而不要用对象名调用虚函应通过指针或引用调用虚函数,而不要用对象名调用

48、虚函数,这样才能保证多态性的成立。数,这样才能保证多态性的成立。数,这样才能保证多态性的成立。数,这样才能保证多态性的成立。在派生类中重定义的基类虚函数仍为虚函数,可以省略在派生类中重定义的基类虚函数仍为虚函数,可以省略在派生类中重定义的基类虚函数仍为虚函数,可以省略在派生类中重定义的基类虚函数仍为虚函数,可以省略virtualvirtual。虚函数重定义时,函数的名称、返回值类型、参。虚函数重定义时,函数的名称、返回值类型、参。虚函数重定义时,函数的名称、返回值类型、参。虚函数重定义时,函数的名称、返回值类型、参数类型、个数及顺序与原函数完全一致。数类型、个数及顺序与原函数完全一致。数类型、

49、个数及顺序与原函数完全一致。数类型、个数及顺序与原函数完全一致。虚函数的重定义与一般函数重载不同,一般函数重载只要虚函数的重定义与一般函数重载不同,一般函数重载只要虚函数的重定义与一般函数重载不同,一般函数重载只要虚函数的重定义与一般函数重载不同,一般函数重载只要求函数名称相同,而虚函数定义要求严格一致。求函数名称相同,而虚函数定义要求严格一致。求函数名称相同,而虚函数定义要求严格一致。求函数名称相同,而虚函数定义要求严格一致。构造函数不可以是虚函数,但是析构函数可以是虚函数,构造函数不可以是虚函数,但是析构函数可以是虚函数,构造函数不可以是虚函数,但是析构函数可以是虚函数,构造函数不可以是虚

50、函数,但是析构函数可以是虚函数,而且通常将其声明为虚函数。将析构函数声明为虚函数的而且通常将其声明为虚函数。将析构函数声明为虚函数的而且通常将其声明为虚函数。将析构函数声明为虚函数的而且通常将其声明为虚函数。将析构函数声明为虚函数的目的是使用目的是使用目的是使用目的是使用deletedelete操作符删除一个对象时,能保证对象所操作符删除一个对象时,能保证对象所操作符删除一个对象时,能保证对象所操作符删除一个对象时,能保证对象所属类的析构函数被正确执行。属类的析构函数被正确执行。属类的析构函数被正确执行。属类的析构函数被正确执行。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多

51、态性与虚函数C+面向对象程序设计蚌埠学院计算机系17【例【例9-69-6】析构函数的使用。】析构函数的使用。n n见教材见教材见教材见教材P121P121n n程序运行结果:程序运行结果:程序运行结果:程序运行结果:基类中的析构函数基类中的析构函数基类中的析构函数基类中的析构函数n n程序说明:在本例中,基类的析构函数不是虚函数。在函程序说明:在本例中,基类的析构函数不是虚函数。在函程序说明:在本例中,基类的析构函数不是虚函数。在函程序说明:在本例中,基类的析构函数不是虚函数。在函数数数数foofoo中,用运算符中,用运算符中,用运算符中,用运算符newnew创建派生类创建派生类创建派生类创建

52、派生类B B的一个对象(其数据的一个对象(其数据的一个对象(其数据的一个对象(其数据成员为成员为成员为成员为2020个字符)。然后将该对象的地址赋值给基类的指个字符)。然后将该对象的地址赋值给基类的指个字符)。然后将该对象的地址赋值给基类的指个字符)。然后将该对象的地址赋值给基类的指针针针针k k,即用基类指针指向派生类对象,在函数,即用基类指针指向派生类对象,在函数,即用基类指针指向派生类对象,在函数,即用基类指针指向派生类对象,在函数foofoo中执行语中执行语中执行语中执行语句句句句 delete k delete k 时,实际上是调用基类的析构函数。时,实际上是调用基类的析构函数。时,

53、实际上是调用基类的析构函数。时,实际上是调用基类的析构函数。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系18【例【例9-79-7】虚析构函数的使用。】虚析构函数的使用。n n在【例在【例在【例在【例9-69-6】的基础上对基类】的基础上对基类】的基础上对基类】的基础上对基类A A做如下的修改。做如下的修改。做如下的修改。做如下的修改。class Aclass Aclass Aclass A public:public:public:public: A() a = new char10; A() a = new char10;

54、A() a = new char10; A() a = new char10; virtual A() /virtual A() /virtual A() /virtual A() /虚析构函数虚析构函数虚析构函数虚析构函数 delete a;delete a;delete a;delete a; coutcoutcoutcout基类中的析构函数基类中的析构函数基类中的析构函数基类中的析构函数endl;endl;endl;endl; private:private:private:private: char * a; char * a; char * a; char * a;程序运行结果:程序

55、运行结果:程序运行结果:程序运行结果:派生类中的析构函数派生类中的析构函数派生类中的析构函数派生类中的析构函数基类中的析构函数基类中的析构函数基类中的析构函数基类中的析构函数http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系199.3 在成员函数中调用虚函数在基类或派生类的成员函数中,可以直接调用该类层在基类或派生类的成员函数中,可以直接调用该类层次中的虚函数。次中的虚函数。【例【例9-89-8】成员函数中调用虚函数的方法。】成员函数中调用虚函数的方法。见教材见教材P123P123程序运行结果:程序运行结果:x=5x=5y=8y=8

56、http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系209.4 在构造函数中调用虚函数n n在建立了类层次,基类定义了虚函数并且在派生类中重新在建立了类层次,基类定义了虚函数并且在派生类中重新在建立了类层次,基类定义了虚函数并且在派生类中重新在建立了类层次,基类定义了虚函数并且在派生类中重新定义了该函数之后,函数的调用采用迟后联编,实现了多定义了该函数之后,函数的调用采用迟后联编,实现了多定义了该函数之后,函数的调用采用迟后联编,实现了多定义了该函数之后,函数的调用采用迟后联编,实现了多态性。在创建类的对象的过程中,总是先调用基类构造

57、函态性。在创建类的对象的过程中,总是先调用基类构造函态性。在创建类的对象的过程中,总是先调用基类构造函态性。在创建类的对象的过程中,总是先调用基类构造函数,建立基类子对象,然后建立自己的成员。所以,在构数,建立基类子对象,然后建立自己的成员。所以,在构数,建立基类子对象,然后建立自己的成员。所以,在构数,建立基类子对象,然后建立自己的成员。所以,在构造函数中调用虚函数时,采用先期联编,即构造函数所调造函数中调用虚函数时,采用先期联编,即构造函数所调造函数中调用虚函数时,采用先期联编,即构造函数所调造函数中调用虚函数时,采用先期联编,即构造函数所调用的虚函数是自己类中或基类定义的函数,而不是在派

58、生用的虚函数是自己类中或基类定义的函数,而不是在派生用的虚函数是自己类中或基类定义的函数,而不是在派生用的虚函数是自己类中或基类定义的函数,而不是在派生类中重新定义的同名函数。应该注意,迟后联编出现在创类中重新定义的同名函数。应该注意,迟后联编出现在创类中重新定义的同名函数。应该注意,迟后联编出现在创类中重新定义的同名函数。应该注意,迟后联编出现在创建了类的对象之后;在对象存在之前,都是采用静态联编。建了类的对象之后;在对象存在之前,都是采用静态联编。建了类的对象之后;在对象存在之前,都是采用静态联编。建了类的对象之后;在对象存在之前,都是采用静态联编。http:/ 多态性与虚函数【大学课件】

59、C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系21【例【例9-99-9】构造函数中虚函数的应用。】构造函数中虚函数的应用。n n见教材见教材见教材见教材P124P124n n程序运行结果:程序运行结果:程序运行结果:程序运行结果:基类中的成员函数基类中的成员函数基类中的成员函数基类中的成员函数基类中的成员函数基类中的成员函数基类中的成员函数基类中的成员函数基类中的成员函数基类中的成员函数基类中的成员函数基类中的成员函数http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系229.5 纯虚函数和抽象类在许多情况下

60、,在基类中不能为虚函数给出一个有意义的定义,在许多情况下,在基类中不能为虚函数给出一个有意义的定义,在许多情况下,在基类中不能为虚函数给出一个有意义的定义,在许多情况下,在基类中不能为虚函数给出一个有意义的定义,这时可以将它说明为纯虚函数这时可以将它说明为纯虚函数这时可以将它说明为纯虚函数这时可以将它说明为纯虚函数(null virtual function)(null virtual function)。具体的函数定。具体的函数定。具体的函数定。具体的函数定义由派生类给出。纯虚函数的一般形式为:义由派生类给出。纯虚函数的一般形式为:义由派生类给出。纯虚函数的一般形式为:义由派生类给出。纯虚函

61、数的一般形式为:virtual virtual 返回类型返回类型返回类型返回类型 函数名(参数表)函数名(参数表)函数名(参数表)函数名(参数表)= 0;= 0;纯虚函数的函数体是空的。具有纯虚函数的类称为抽象类纯虚函数的函数体是空的。具有纯虚函数的类称为抽象类纯虚函数的函数体是空的。具有纯虚函数的类称为抽象类纯虚函数的函数体是空的。具有纯虚函数的类称为抽象类(abstract classabstract class),反之,称为具体类),反之,称为具体类),反之,称为具体类),反之,称为具体类(concrete class)(concrete class)。一个抽象类。一个抽象类。一个抽象类

62、。一个抽象类至少具有一个纯虚函数。在使用抽象类和纯虚函数时必须注意以下几至少具有一个纯虚函数。在使用抽象类和纯虚函数时必须注意以下几至少具有一个纯虚函数。在使用抽象类和纯虚函数时必须注意以下几至少具有一个纯虚函数。在使用抽象类和纯虚函数时必须注意以下几点:点:点:点:抽象类不能实例化,即不能创建对象。抽象类不能实例化,即不能创建对象。抽象类不能实例化,即不能创建对象。抽象类不能实例化,即不能创建对象。必须从带有纯虚函数的基类(抽象类)中派生出派生类,在派生必须从带有纯虚函数的基类(抽象类)中派生出派生类,在派生必须从带有纯虚函数的基类(抽象类)中派生出派生类,在派生必须从带有纯虚函数的基类(抽

63、象类)中派生出派生类,在派生类中定义出自己的,与纯虚函数同名的重载函数,从而使派生类成为类中定义出自己的,与纯虚函数同名的重载函数,从而使派生类成为类中定义出自己的,与纯虚函数同名的重载函数,从而使派生类成为类中定义出自己的,与纯虚函数同名的重载函数,从而使派生类成为一个具体类,这样就可以用派生类来定义对象。若没有重新定义纯虚一个具体类,这样就可以用派生类来定义对象。若没有重新定义纯虚一个具体类,这样就可以用派生类来定义对象。若没有重新定义纯虚一个具体类,这样就可以用派生类来定义对象。若没有重新定义纯虚函数,则必须将该虚函数声明为纯虚函数,该派生类仍然是一个抽象函数,则必须将该虚函数声明为纯虚

64、函数,该派生类仍然是一个抽象函数,则必须将该虚函数声明为纯虚函数,该派生类仍然是一个抽象函数,则必须将该虚函数声明为纯虚函数,该派生类仍然是一个抽象类。类。类。类。抽象类只作为基类被继承,派生新类。无派生类的抽象类是没有意抽象类只作为基类被继承,派生新类。无派生类的抽象类是没有意抽象类只作为基类被继承,派生新类。无派生类的抽象类是没有意抽象类只作为基类被继承,派生新类。无派生类的抽象类是没有意义的。因此抽象类只是用于被继承,仅作为一个接口,具体的功能在义的。因此抽象类只是用于被继承,仅作为一个接口,具体的功能在义的。因此抽象类只是用于被继承,仅作为一个接口,具体的功能在义的。因此抽象类只是用于

65、被继承,仅作为一个接口,具体的功能在其派生类中实现。其派生类中实现。其派生类中实现。其派生类中实现。不能创建一个抽象类的对象,但可以声明一个抽象类的指针或引用,不能创建一个抽象类的对象,但可以声明一个抽象类的指针或引用,不能创建一个抽象类的对象,但可以声明一个抽象类的指针或引用,不能创建一个抽象类的对象,但可以声明一个抽象类的指针或引用,这个指针或引用必然指向派生类对象,从而实现多态性。这个指针或引用必然指向派生类对象,从而实现多态性。这个指针或引用必然指向派生类对象,从而实现多态性。这个指针或引用必然指向派生类对象,从而实现多态性。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计

66、 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系23n n纯虚函数的一个类层次见图纯虚函数的一个类层次见图纯虚函数的一个类层次见图纯虚函数的一个类层次见图5.25.2所示。所示。所示。所示。n n在图在图在图在图9-29-2中,图形类中,图形类中,图形类中,图形类ShapeShape是一个抽象类。图形是一个抽象是一个抽象类。图形是一个抽象是一个抽象类。图形是一个抽象是一个抽象类。图形是一个抽象概念,若不具体地说明是哪种图形,图形面积就没办法计概念,若不具体地说明是哪种图形,图形面积就没办法计概念,若不具体地说明是哪种图形,图形面积就没办法计概念,若不具体地说明是哪种图形,图形面积就没办法计

67、算。因此,在算。因此,在算。因此,在算。因此,在ShapeShape类中无法定义有实际意义的函数具体类中无法定义有实际意义的函数具体类中无法定义有实际意义的函数具体类中无法定义有实际意义的函数具体计算面积,计算面积的函数计算面积,计算面积的函数计算面积,计算面积的函数计算面积,计算面积的函数area()area()只能定义为纯虚函数。只能定义为纯虚函数。只能定义为纯虚函数。只能定义为纯虚函数。因此在派生类因此在派生类因此在派生类因此在派生类CircleCircle类和类和类和类和RectangleRectangle类中必须给出类中必须给出类中必须给出类中必须给出area()area()函函函函

68、数的重载,成为具体类,就可以创建具体对象,从而计算数的重载,成为具体类,就可以创建具体对象,从而计算数的重载,成为具体类,就可以创建具体对象,从而计算数的重载,成为具体类,就可以创建具体对象,从而计算具体图形的面积。具体图形的面积。具体图形的面积。具体图形的面积。Shape类Circle类Rectangle类图9.2 类层次http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系24【例【例9-109-10】纯虚函数的用法。】纯虚函数的用法。n n程序见教材程序见教材程序见教材程序见教材P126P126n n程序运行结果:程序运行结果:程

69、序运行结果:程序运行结果:圆的半径圆的半径圆的半径圆的半径 : 5 : 5圆的面积圆的面积圆的面积圆的面积 : 78.5398 : 78.5398矩形的边长矩形的边长矩形的边长矩形的边长 : 2 4 : 2 4矩形的面积矩形的面积矩形的面积矩形的面积 : 8 : 8http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数C+面向对象程序设计蚌埠学院计算机系25本章小结n n多态性是面向对象程序设计的一个重要特征,其本意是多态性是面向对象程序设计的一个重要特征,其本意是多态性是面向对象程序设计的一个重要特征,其本意是多态性是面向对象程序设计的一个重要特征,其本意是“拥有拥有拥

70、有拥有多种形态多种形态多种形态多种形态”。C+C+C+C+中,多态性是指具有不同功能的函数共用同一中,多态性是指具有不同功能的函数共用同一中,多态性是指具有不同功能的函数共用同一中,多态性是指具有不同功能的函数共用同一个函数名。个函数名。个函数名。个函数名。C+C+C+C+中的多态性有两种类型:静态多态性和动态多态中的多态性有两种类型:静态多态性和动态多态中的多态性有两种类型:静态多态性和动态多态中的多态性有两种类型:静态多态性和动态多态性。函数重载属于静态多态性,程序在编译时就能确定调用哪性。函数重载属于静态多态性,程序在编译时就能确定调用哪性。函数重载属于静态多态性,程序在编译时就能确定调

71、用哪性。函数重载属于静态多态性,程序在编译时就能确定调用哪个函数;动态多态性是指在动态联编下实现的多态性,只有在个函数;动态多态性是指在动态联编下实现的多态性,只有在个函数;动态多态性是指在动态联编下实现的多态性,只有在个函数;动态多态性是指在动态联编下实现的多态性,只有在程序运行时才能解决函数的调用问题。程序运行时才能解决函数的调用问题。程序运行时才能解决函数的调用问题。程序运行时才能解决函数的调用问题。n n虚函数是实现动态多态性的关键。没有虚函数不可能实现动态虚函数是实现动态多态性的关键。没有虚函数不可能实现动态虚函数是实现动态多态性的关键。没有虚函数不可能实现动态虚函数是实现动态多态性

72、的关键。没有虚函数不可能实现动态联编。虚函数的声明比较简单,只要在联编。虚函数的声明比较简单,只要在联编。虚函数的声明比较简单,只要在联编。虚函数的声明比较简单,只要在“感兴趣感兴趣感兴趣感兴趣”的成员函数的成员函数的成员函数的成员函数前加上前加上前加上前加上virtualvirtualvirtualvirtual关键字即可,难的是如何理解虚函数的功能。根关键字即可,难的是如何理解虚函数的功能。根关键字即可,难的是如何理解虚函数的功能。根关键字即可,难的是如何理解虚函数的功能。根据赋值兼容规则,可以把派生类对象地址赋给基类指针,或是据赋值兼容规则,可以把派生类对象地址赋给基类指针,或是据赋值兼

73、容规则,可以把派生类对象地址赋给基类指针,或是据赋值兼容规则,可以把派生类对象地址赋给基类指针,或是用派生类对象来初始化基类引用,如果没有声明虚函数,通过用派生类对象来初始化基类引用,如果没有声明虚函数,通过用派生类对象来初始化基类引用,如果没有声明虚函数,通过用派生类对象来初始化基类引用,如果没有声明虚函数,通过基类指针或基类引用只能访问基类的成员函数;若声明了虚函基类指针或基类引用只能访问基类的成员函数;若声明了虚函基类指针或基类引用只能访问基类的成员函数;若声明了虚函基类指针或基类引用只能访问基类的成员函数;若声明了虚函数,那么通过基类指针或基类引用,就能根据调用对象的不同数,那么通过基

74、类指针或基类引用,就能根据调用对象的不同数,那么通过基类指针或基类引用,就能根据调用对象的不同数,那么通过基类指针或基类引用,就能根据调用对象的不同去访问不同派生类的成员函数,这就是虚函数的神奇功能。虚去访问不同派生类的成员函数,这就是虚函数的神奇功能。虚去访问不同派生类的成员函数,这就是虚函数的神奇功能。虚去访问不同派生类的成员函数,这就是虚函数的神奇功能。虚函数的使用,体现了函数的使用,体现了函数的使用,体现了函数的使用,体现了“一个接口,多种方法一个接口,多种方法一个接口,多种方法一个接口,多种方法”的面向对象编程的面向对象编程的面向对象编程的面向对象编程思想。思想。思想。思想。http:/ 多态性与虚函数【大学课件】C+面向对象程序设计 多态性与虚函数

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号