第16讲多态性与虚函数 教学目的与要求: 了解虚函数的作用和功能 掌握虚函数实现多态性。 教学内容提要: 多态性的概念 2、函数重载; 3、虚函数; 教学重点:虚函数的声明和使用。 教学难点:虚函数的声明和使用。 教学进度:P162,P200~P212 教学过程:
第16讲 多态性与虚函数 •教学目的与要求: 了解虚函数的作用和功能。 掌握虚函数实现多态性。 •教学内容提要: 1、 多态性的概念; 2、函数重载; 3、虚函数; •教学重点:虚函数的声明和使用。 •教学难点:虚函数的声明和使用。 •教学进度:P162,P200~P212 •教学过程:
16.1多态性概述 多态就是指不同的对象接受到相同的消息时产生不同的响应动 作,即对应相同的函数名,却执行了不同的函数体(当然,这 些函数在 要事先定义好,以便调用) 种把程序标示符与和一个存储地址相联系的过程,称为联编 binding,又译为绑定)
16.1 多态性概述 多态就是指不同的对象接受到相同的消息时产生不同的响应动 作,即对应相同的函数名,却执行了不同的函数体(当然,这 些函数体还是要事先定义好,以便调用)。 种把程序标示符与和一个存储地址相联系的过程,称为联编 (binding,又译为绑定)
161.1多态的分类 C++中的多态性可以分为四类: 参数多态: 包含多态:指在基类及其派生类族中同名函数的不 同函数实现,及其在运行时的不同响应。 重载多态:函数重载 强制多态:不同类型的数据类型进行混合运算时要 进行的强制类型转换。 前面两种统称为通用多态,而后面两种统称为专用 多态
16.1.1 多态的分类 C++中的多态性可以分为四类: 参数多态: 包含多态:指在基类及其派生类族中同名函数的不 同函数实现,及其在运行时的不同响应。 重载多态:函数重载 强制多态:不同类型的数据类型进行混合运算时要 进行的强制类型转换。 前面两种统称为通用多态,而后面两种统称为专用 多态
16.12多态的实现 多态从实现的角度来讲可以划分为两类: 编译时的多态和运行时的多态。 编译时的多态是通过静态联编来实现的。静 态联编就是在编译阶段完成的联编。编译时多态 性主要是通过函数重载和运算符重载实现的。 运行时的多态是用动态联编实现的。动态联编 是运行阶段完成的联编。运行时多态性主要是通 过虚函数来实现的
16.1.2多态的实现 多态从实现的角度来讲可以划分为两类: 编译时的多态和运行时的多态。 编译时的多态是通过静态联编来实现的。静 态联编就是在编译阶段完成的联编。编译时多态 性主要是通过函数重载和运算符重载实现的。 运行时的多态是用动态联编实现的。动态联编 是运行阶段完成的联编。运行时多态性主要是通 过虚函数来实现的
162普通成员函数重载 在C++语言中,只有在声明函数原型时形式参数的个数 或者对应位置的类型不同,两个或更多的函数就可以共用 个名字。这种在同一作用域中允许多个函数使用同一函数名 的措施被称为重载( overloading)。函数重载是C++程序获 得多态性的途径之一。 1621函数重载的方法 函数重载要求编译器能够唯一地确定调用一个函数时应 执行哪个函数代码,既采用哪个函数实现。确定函数实现时, 要求从函数参数的个数和类型上来区分。这就是说,进行函 数重载时,要求同名函数在参数个数上不同,或者参数类型 不同。否则,将无法实现函数重载
16.2 普通成员函数重载 在C++语言中,只有在声明函数原型时形式参数的个数 或者对应位置的类型不同,两个或更多的函数就可以共用一 个名字。这种在同一作用域中允许多个函数使用同一函数名 的措施被称为重载(overloading)。函数重载是C++程序获 得多态性的途径之一。 16.2.1 函数重载的方法 函数重载要求编译器能够唯一地确定调用一个函数时应 执行哪个函数代码,既采用哪个函数实现。确定函数实现时, 要求从函数参数的个数和类型上来区分。这就是说,进行函 数重载时,要求同名函数在参数个数上不同,或者参数类型 不同。否则,将无法实现函数重载
例16.1:用重载函数实现求圆和矩形的周长。 #include void maine const double pl31415 double length(float r) float a, b, r; return 2*Prr cou>rg double length(float x, float y cout>a>>b cout<<”矩形周 长:”<< ength(a,b)<<endl;
#include const double PI=3.1415; double length(float r) { return 2*PI*r; } double length(float x,float y) { return 2*(x+y); } 例16.1:用重载函数实现求圆和矩形的周长。 void main() { float a,b,r; cout>r; cout>a>>b; cout<<”矩形周 长:”<<length(a,b)<<endl; }
1622函数重载的表示形式 普通成员函数重载可表达为两种形式: 1.在一个类说明中重载 例如: Show(int, char )i Show( char *, float ) 2.基类的成员函数在派生类重载。有3种编译区分方 法 (1)根据参数的特征加以区分 例如: Show(int,char)与 Show( char *, float 不是同一函数,编译能够区分
16.2.2 函数重载的表示形式 普通成员函数重载可表达为两种形式: 1. 在一个类说明中重载 例如: Show ( int , char ) ; Show ( char * , float ) ; 2. 基类的成员函数在派生类重载。有3种编译区分方 法 (1)根据参数的特征加以区分 例如: Show ( int , char ) 与 Show ( char * , float ) 不是同一函数,编译能够区分
(2)使用“:”加以区分 例如: A∷:Show( 有别于B:Show() (3)根据类对象加以区分 例如: Aobj Show()调用A:Show() Bobj Show()调用B:Show()
(2)使用“:: ”加以区分 例如: A :: Show ( ) 有别于 B :: Show ( ) (3)根据类对象加以区分 例如: Aobj.Show ( )调用 A :: Show ( ) Bobj.Show ( )调用 B :: Show ( )
#include class point void maino int x,y; public point(int a, int b) point p(20, 20); Rx=a;y=b) float areaoireturn 0; circle c(8, 8, 30); cout<<p area(<<endl class circle: public point int radius; cout<<carea(<<endl; public cout<<c point: area(<<endl; circle(int a, int b, int r): point(a, b) i radius=r; f float areao f return 3.1416 radius*radius;
#include class point { int x,y; public: point(int a ,int b) {x=a;y=b} float area(){return 0;} }; class circle:public point { int radius; public: circle(int a,int b,int r):point(a,b) { radius=r;} float area() { return 3.1416*radius*radius;} }; void main() { point p(20,20); circle c(8,8,30); cout<<p.area()<<endl; cout<<c.area()<<endl; cout<<c.point::area()<<endl; }
63虚函数 虚函数提供了一种更为灵活的多态性机制。虚函数允 许函数调用与函数体之间的联系在运行时才建立,也就是 在运行时才决定如何动作,即所谓的动态联编。 631虚函数的引入 例162虚函数的引例。 maino #includesiostream. h> Aa, pc; class At public Bb: void shower coutshow; class b: publica i pc=&b; pc->show 0; public: turn o void shows cout<<"B";
6.3 虚函数 虚函数提供了一种更为灵活的多态性机制。虚函数允 许函数调用与函数体之间的联系在运行时才建立,也就是 在运行时才决定如何动作,即所谓的动态联编。 6.3.1 虚函数的引入 例16.2 虚函数的引例。 #include class A{ public: void show(){ coutshow(); pc=&b; pc->show(); return 0; }