第05章多态性和虚函数.ppt
《第05章多态性和虚函数.ppt》由会员分享,可在线阅读,更多相关《第05章多态性和虚函数.ppt(91页珍藏版)》请在课桌文档上搜索。
1、多态性和虚函数,第05章,主要内容,5.2 虚函数,5.4 运算符重载,5.3 纯虚函数和抽象类,5.1 重载与覆盖,什么是多态性?,在C+中通过重载、覆盖、运算符重载、虚函数等技术,使得基类和派生类中可以出现同名的成员函数。不同的成员函数被调用时表现出不同的行为,表现出很强的灵活性,称为多态性。成员函数重载成员函数覆盖虚函数运算符重载,静态多态性和动态多态性,静态多态性:编译时的多态性,成员函数重载、覆盖、运算符重载都属于静态多态性。编译器根据实参数据类型或对象的数据类型,在编译时就确定调用哪个函数。动态多态性:运行时多态性,通过虚函数来实现。通过虚函数实现的动态多态性,在代码执行的过程中决
2、定调用哪个函数。,1、成员函数重载和覆盖,重载:同一个类中,存在名称相同但“签名不同”的成员函数(函数参数类型或个数不同),编译时根据实参类型确定调用的是哪个版本的函数。覆盖:派生类和基类存在名称相同的成员函数,实现派生类方法覆盖(改造)基类方法的功能。如果要访问基类被覆盖方法,需要使用类名前缀。,2、成员函数重载,class Interint num;public:Inter(int a)num=a;void SetNum(int a)num=a;void SetNum(double a)num=int(a+0.5);void show()coutnumendl;,成员函数重载,void m
3、ain()Inter i(3);i.show();i.SetNum(5);i.show();i.SetNum(6.6);i.show();,运行结果357,3、覆盖技术,在派生类中定义与基类同名的成员函数后,会出现覆盖现象;实现重新定义基类成员函数。const double PI=3.14159;class Point double x,y;public:Point(double i,double j)x=i;y=j;double area()return 0;;,覆盖技术,class Circle:public Point double radius;public:Circle(double
4、 a,double b,double r):Point(a,b)radius=r;double area()return PI*radius*radius;;,覆盖技术,void main()Point a(1.5,6.7);Circle c(1.5,6.7,2.5);coutarea()endl;,运行结果area of a:0area of c:19.6349area of c:0,覆盖技术,a.area()表达式明确告诉编译器,它调用的是Point的成员函数area,输出0。c.area()表达式明确表示调用的是Circle的成员函数area,输出19.6349。因为指针p的数据类型是P
5、oint,根据赋值兼容性规则,p-area(),调用的是Point的成员函数,输出0。,4、访问被覆盖的方法,class CPointint x,y;public:CPoint()x=0;y=0;CPoint(int a,int b)x=a;y=b;void Set(int a,int b)x=a;y=b;void Show()coutx“,”yendl;,访问被覆盖的方法,class Circle:public CPointint radius;public:Circle(int a,int b,int r):CPoint(a,b)radius=r;void Set(int a,int b,
6、int r)CPoint:Set(a,b);radius=r;void Show()coutradius“,”;CPoint:Show();,访问被覆盖的方法,void main()Circle c(3,4,5);c.Show();c.Set(5,6,7);c.Show();c.CPoint:Set(7,8);c.CPoint:Show();,间接调用基类成员函数,限定调用基类成员,不好!,运行结果5,3,47,5,67,8,主要内容,5.2 虚函数,5.4 运算符重载,5.3 纯虚函数和抽象类,5.1 重载与覆盖,1、为什么要运行时多态?,class Mammalint age;double
7、 weight;public:Mammal(int a,double w)age=a;weight=w;void Shout()cout“Im a mammal.n”;,为什么要运行时多态?,class Dog:public Mammalpublic:Dog(int a,double w):Mammal(a,w)void Shout()cout“woo.n”;class Cat:public Mammalpublic:Cat(int a,double w):Mammal(a,w)void Shout()cout“meow.n”;,为什么要运行时多态?,void Shout(Mammal*p)p
8、-Shout();void main()Mammal m(3,5);Dog dog(4,6);Cat cat(4,7);Shout(,用户的期望调用基类Shout调用Dog类Shout调用Cat类Shout,?,输出结果Im a mammal.Im a mammal.Im a mammal.,编译器无能为力!,void Shout(Mammal*p)p-Shout();void main()Mammal m(3,5);Dog dog(4,6);Cat cat(4,7);Shout(,实际调用情况调用基类Shout调用基类Shout调用基类Shout,编译时就已经确定的事实,勉强的方法,void
9、 main()Mammal m(3,5);Dog dog(4,6);Cat cat(4,7);m.Shout();dog.Shout();cat.Shout();,假设有100个不同类型的动物,代码要写100遍?!,2、解决之道:虚函数,class Mammalint age;double weight;public:Mammal(int a,double w)age=a;weight=w;virtual void Shout()cout“Im a mammal.n”;,私有函数不行,神奇的变化,/Dog类和Cat类保持不变void Shout(Mammal*p)p-Shout();void
10、main()Mammal m(3,5);Dog dog(4,6);Cat cat(4,7);Shout(,实际调用情况调用基类Shout调用Dog类Shout调用Cat类Shout,输出结果Im a mammal.woo.meow.,一个接口,多种方法,void Shout(Mammal*p)p-Shout();void main()Mammal*p;if()p=new Dog(3,4);else p=new Cat(5,6);Shout(p);delete p;,传过去什么对象,调用对应的Shout,静态联编无法实现,3、虚函数的说明,虚函数实现动态性关键在于使用基类指针,当用基类指针指向不
11、同对象时,到底调用哪个版本成员函数,取决于所指向对象的类型。如果指向Dog类对象,则调用Dog类的Shout;如果指向Cat类对象,则调用Cat类的Shout;如果指向Mammal类对象,则调用基类的Shout。用虚函数实现的多态性是代码执行过程中的多态,大大增加了程序的灵活性。使用基类引用也可以实现动态多态性。,说明,在基类中定义虚函数后,往往在派生类中重新定义(确保返回类型和参数个数及类型完全匹配),才能形成动态多态性。在基类中定义的虚函数,在派生类中重定义后仍然为虚函数,即使不写virtual关键字。虚函数必须是类的公有或保护成员函数;友元函数和普通函数不能声明为虚函数;构造函数和静态成
12、员函数不能被声明为虚函数;析构函数可以被声明为虚函数。,另一个示例,图形类基类:CShape派生类:CRect、CCircle、CTriangle应用的思路绘图程序中,设计一个链表,保存用户绘制的各种图形对象;刷新屏幕时,通过遍历链表,绘制所有对象。,基类的基本功能,class CShapepublic:void Display();,派生类:CRect,class CRect:public CShapeprivate:CPoint p1,p2;public:void Display();,派生类:CCircle,class CCircle:public CShapeprivate:CPoin
13、t center;int radius;public:void Display();,派生类:CTriangle,class CTriangle:public CShapeprivate:CPoint p1,p2,p3;public:void Display();,链表的遍历,void ReDraw(CShape*pHead)while(!pHead)pHead-Display();pHead=pHead-next;,问题:实际调用的都是基类的Display没有按预计的情况执行。,解决之道:虚函数,class CShapepublic:virtual void Display();,4、寻根求
14、源:静态多态性,Mammal*p1,*p2;Dog dog(3,5);Cat cat(5,7);p1=,5、寻根求源:虚函数,class Apublic:int a;A(int x)a=x;virtual void Show()coutaendl;virtual void inc()a+;void sub()a-;/非虚函数;,虚函数原理,class B:public Apublic:int b;B(int x,int y):A(x)b=y;void Show()coutbendl;void inc()b+;void sub()b-;,虚函数原理,class C:public Apublic:
15、int c;C(int x,int y):A(x)c=y;void Show()coutcendl;void inc()c+;void sub()c-;,虚函数原理,void main()A aa(3);B bb(4,5);C cc(6,7);,虚函数原理:基类对象,void main()A aa(3);A*p=,虚函数原理:派生类对象,void main()B bb(4,5);A*p=,虚函数原理:派生类对象,void main()C cc(6,7);A*p=,6、虚析构函数,C+中规定,某个类中含有虚函数,则应该将其析构函数设置为虚函数。否则容易出现内存泄漏等问题。class Shaped
16、ouble x,y;public:virtual Shape()virtual double area()return 0;,派生类,const double PI=3.1415926;class Circle:public Shapedouble radius;public:Circle(double x,double y,double z):Shape(x,y)radius=z;double area()return PI*radius*radius;Circle();,虚析构函数:原因,如果不采用虚析构函数Shape*p=new Circle(3,5,2);delete p;,由于静态联
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 05 多态性 函数
链接地址:https://www.desk33.com/p-675590.html