多态性与虚函数PPT讲稿.ppt
多态性与虚函数1第1页,共25页,编辑于2022年,星期六第6章 多态性与虚函数2第2页,共25页,编辑于2022年,星期六6.1 多态性的概念多态性的概念6.2 一个典型的例子一个典型的例子6.3 虚函数虚函数6.4 纯虚函数与抽象类纯虚函数与抽象类3第3页,共25页,编辑于2022年,星期六6.1 多态性的概念多态性的概念多多多多态态态态性性性性:调调调调用用用用同同同同一一一一个个个个函函函函数数数数名名名名,可可可可以以以以根根根根据据据据需需需需要要要要实实实实现现现现不不不不同同同同的功能。的功能。的功能。的功能。多态性是面向对象程序设计的关键技术。多态性是面向对象程序设计的关键技术。多态性是面向对象程序设计的关键技术。多态性是面向对象程序设计的关键技术。编译时的多态性(函数重载)编译时的多态性(函数重载)编译时的多态性(函数重载)编译时的多态性(函数重载)运行时的多态性运行时的多态性运行时的多态性运行时的多态性(虚函数)(虚函数)(虚函数)(虚函数)多态性多态性多态性多态性运运运运行行行行时时时时的的的的多多多多态态态态性性性性是是是是指指指指在在在在程程程程序序序序执执执执行行行行之之之之前前前前,根根根根据据据据函函函函数数数数名名名名和和和和参参参参数数数数无无无无法法法法确确确确定定定定应应应应该该该该调调调调用用用用哪哪哪哪一一一一个个个个函函函函数数数数,必必必必须须须须在在在在程程程程序序序序的的的的执执执执行行行行过过过过程程程程中中中中,根据具体的执行情况来动态地确定。根据具体的执行情况来动态地确定。根据具体的执行情况来动态地确定。根据具体的执行情况来动态地确定。4第4页,共25页,编辑于2022年,星期六可以将一个派生类对象的地址赋给基类的指针变量可以将一个派生类对象的地址赋给基类的指针变量可以将一个派生类对象的地址赋给基类的指针变量可以将一个派生类对象的地址赋给基类的指针变量。基类对象基类对象基类对象基类对象派生类对象派生类对象派生类对象派生类对象Base b;Base b;Derive d;Derive d;Base*basep;Base*basep;basepbasep=&b;basep=&b;basepbasep=&d;basep=&d;basepbasep只能引用从基类继只能引用从基类继只能引用从基类继只能引用从基类继承来的成员。承来的成员。承来的成员。承来的成员。x xShow()Show()x xShow()Show()y yShow()Show()basep-Show();basep-Show();basep-Show()basep-Show()基类指针基类指针派生类对象派生类对象基类对象基类对象5第5页,共25页,编辑于2022年,星期六class Point class Point float x,y;float x,y;public:Point()public:Point()Point(float i,float j)x=i;y=j;Point(float i,float j)x=i;y=j;float area(void)return 0.0;float area(void)return 0.0;const float Pi=3.14159F;const float Pi=3.14159F;class Circle:public Point /class Circle:public Point /类类类类PointPoint的派生类的派生类的派生类的派生类 float radius;float radius;public:Circle(float r)radius=r;public:Circle(float r)radius=r;float area(void)return Pi*radius*radius;float area(void)return Pi*radius*radius;void main(void)void main(void)Point*pp;/Point*pp;/基类指针,可将派生类对象的地址赋给基类指针基类指针,可将派生类对象的地址赋给基类指针基类指针,可将派生类对象的地址赋给基类指针基类指针,可将派生类对象的地址赋给基类指针 Circle c(5.4321);pp=&c;Circle c(5.4321);pp=&c;coutarea()endl;/coutarea()Show()basep-Show()Base*basep;Base*basep;basep=&b;basep=&b;basep=&d;basep=&d;basep-Show();basep-Show();要指向派生类新增的成员函数要指向派生类新增的成员函数要指向派生类新增的成员函数要指向派生类新增的成员函数需要将基类中的需要将基类中的需要将基类中的需要将基类中的Show()Show()说明为虚函数说明为虚函数说明为虚函数说明为虚函数7第7页,共25页,编辑于2022年,星期六若若若若要要要要访访访访问问问问派派派派生生生生类类类类中中中中相相相相同同同同名名名名字字字字的的的的函函函函数数数数,必必必必须须须须将将将将基基基基类类类类中中中中的的的的同同同同名名名名函函函函数数数数定定定定义义义义为为为为虚虚虚虚函函函函数数数数,这这这这样样样样,将将将将不不不不同同同同的的的的派派派派生生生生类类类类对对对对象象象象的的的的地地地地址址址址赋赋赋赋给给给给基基基基类类类类的的的的指指指指针针针针变变变变量量量量后后后后,就就就就可可可可以以以以动动动动态态态态地地地地根根根根据据据据这这这这种种种种赋赋赋赋值值值值语语语语句句句句调调调调用用用用不不不不同类中的函数同类中的函数同类中的函数同类中的函数。6.2 一个典型的例子一个典型的例子例例例例6.1 6.1 先先先先建建建建立立立立一一一一个个个个PointPoint类类类类,包包包包含含含含数数数数据据据据成成成成员员员员x,x,y y。以以以以它它它它为为为为基基基基类类类类,派派派派生生生生出出出出一一一一个个个个CircleCircle类类类类,增增增增加加加加数数数数据据据据成成成成员员员员r r,再再再再以以以以CircleCircle类类类类为为为为直直直直接接接接基基基基类类类类,派派派派生生生生出出出出一一一一个个个个CylinderCylinder类类类类,再再再再增增增增加加加加数数数数据据据据成成成成员员员员h h。要要要要求求求求编编编编写写写写程程程程序序序序,重重重重载载载载运运运运算算算算符符符符“”,使使使使之之之之能能能能用用用用于于于于输输输输出以上类的对象。出以上类的对象。出以上类的对象。出以上类的对象。(1 1 2 2 3 3)8第8页,共25页,编辑于2022年,星期六6.3 虚函数虚函数6.3.1 虚函数的作用虚函数的作用允允允允许许许许在在在在派派派派生生生生类类类类中中中中重重重重新新新新定定定定义义义义与与与与基基基基类类类类同同同同名名名名的的的的函函函函数数数数,并并并并且且且且可可可可以以以以通过基类的指针去访问基类和派生类中的同名函数。通过基类的指针去访问基类和派生类中的同名函数。通过基类的指针去访问基类和派生类中的同名函数。通过基类的指针去访问基类和派生类中的同名函数。例例例例6.2 6.2 基类与派生类中有同名函数。(基类与派生类中有同名函数。(基类与派生类中有同名函数。(基类与派生类中有同名函数。(1 1 2 2)虚函数的使用方法:虚函数的使用方法:虚函数的使用方法:虚函数的使用方法:(1)(1)在基类中用在基类中用在基类中用在基类中用virtualvirtual声明成员函数为虚函数。声明成员函数为虚函数。声明成员函数为虚函数。声明成员函数为虚函数。(2)(2)在在在在派派派派生生生生类类类类中中中中重重重重新新新新定定定定义义义义此此此此函函函函数数数数,要要要要求求求求函函函函数数数数名名名名、函函函函数数数数类类类类型型型型、函函函函数数数数参参参参数数数数个个个个数数数数和和和和类类类类型型型型全全全全部部部部与与与与基基基基类类类类的的的的虚虚虚虚函函函函数数数数相相相相同同同同,并并并并根根根根据据据据派生类的需要重新定义函数体。派生类的需要重新定义函数体。派生类的需要重新定义函数体。派生类的需要重新定义函数体。9第9页,共25页,编辑于2022年,星期六当当当当一一一一个个个个成成成成员员员员函函函函数数数数被被被被声声声声明明明明为为为为虚虚虚虚函函函函数数数数后后后后,其其其其派派派派生生生生类类类类中中中中的的的的同同同同名名名名函数都自动成为虚函数。函数都自动成为虚函数。函数都自动成为虚函数。函数都自动成为虚函数。(3)(3)定定定定义义义义一一一一个个个个指指指指向向向向基基基基类类类类的的的的指指指指针针针针变变变变量量量量,并并并并使使使使它它它它指指指指向向向向同同同同一一一一类类类类簇簇簇簇中的某一个对象。中的某一个对象。中的某一个对象。中的某一个对象。(4)(4)通通通通过过过过该该该该指指指指针针针针变变变变量量量量调调调调用用用用此此此此虚虚虚虚函函函函数数数数,此此此此时时时时调调调调用用用用的的的的就就就就是是是是指针变量指向对象的同名函数。指针变量指向对象的同名函数。指针变量指向对象的同名函数。指针变量指向对象的同名函数。6.3.2 静态关联与动态关联静态关联与动态关联函函函函数数数数重重重重载载载载和和和和通通通通过过过过对对对对象象象象名名名名调调调调用用用用的的的的虚虚虚虚函函函函数数数数,在在在在编编编编译译译译时时时时即即即即可可可可确确确确定定定定其其其其调调调调用用用用的的的的虚虚虚虚函函函函数数数数属属属属于于于于哪哪哪哪一一一一个个个个类类类类,该该该该过过过过程程程程称称称称为为为为静静静静态态态态关关关关联联联联(static bindingstatic binding)。)。)。)。在在在在运运运运行行行行阶阶阶阶段段段段把把把把虚虚虚虚函函函函数数数数和和和和类类类类对对对对象象象象“绑绑绑绑定定定定”在在在在一一一一起起起起的的的的过过过过程程程程称为称为称为称为动态关联动态关联动态关联动态关联(dynamic bindingdynamic binding)。)。)。)。10第10页,共25页,编辑于2022年,星期六可可可可以以以以在在在在程程程程序序序序运运运运行行行行时时时时通通通通过过过过调调调调用用用用相相相相同同同同的的的的函函函函数数数数名名名名而而而而实实实实现现现现不不不不同同同同功功功功能的函数称为虚函数。能的函数称为虚函数。能的函数称为虚函数。能的函数称为虚函数。定义格式为:定义格式为:定义格式为:定义格式为:virtual virtual FuncName();FuncName();一一一一旦旦旦旦把把把把基基基基类类类类的的的的成成成成员员员员函函函函数数数数定定定定义义义义为为为为虚虚虚虚函函函函数数数数,由由由由基基基基类类类类所所所所派派派派生生生生出出出出来的所有派生类中,该函数均保持虚函数的特性。来的所有派生类中,该函数均保持虚函数的特性。来的所有派生类中,该函数均保持虚函数的特性。来的所有派生类中,该函数均保持虚函数的特性。在在在在派派派派生生生生类类类类中中中中重重重重新新新新定定定定义义义义基基基基类类类类中中中中的的的的虚虚虚虚函函函函数数数数时时时时,可可可可以以以以不不不不用用用用关关关关键键键键字字字字virtualvirtual来修饰这个成员函数来修饰这个成员函数来修饰这个成员函数来修饰这个成员函数 。虚虚虚虚函函函函数数数数是是是是用用用用virtualvirtual修修修修饰饰饰饰的的的的某某某某基基基基类类类类中中中中的的的的protectedprotected或或或或publicpublic成成成成员员员员函函函函数数数数。它它它它可可可可以以以以在在在在派派派派生生生生类类类类中中中中重重重重新新新新定定定定义义义义,以以以以形形形形成成成成不不不不同同同同版版版版本本本本。只只只只有有有有在在在在程程程程序序序序的的的的执执执执行行行行过过过过程程程程中中中中,依依依依据据据据指指指指针针针针具具具具体体体体指指指指向向向向哪哪哪哪个个个个类类类类的的的的对对对对象象象象,才才才才能确定激活哪一个版本,实现动态关联能确定激活哪一个版本,实现动态关联能确定激活哪一个版本,实现动态关联能确定激活哪一个版本,实现动态关联。11第11页,共25页,编辑于2022年,星期六class A class A protected:int x;protected:int x;public:A()x=1000;public:A()x=1000;virtual void print()cout x=xt;/virtual void print()cout x=xt;/虚函数虚函数虚函数虚函数;class B:public A int y;class B:public A int y;public:public:B()y=2000;B()y=2000;void print()cout y=yt;/void print()cout y=yt;/派生虚函数派生虚函数派生虚函数派生虚函数;class C:public A int z;class C:public A int z;public:C()z=3000;public:C()z=3000;void print()cout z=zn;/void print()cout z=zprint();/pa=&a;pa-print();/调用类调用类调用类调用类A A的虚函数的虚函数的虚函数的虚函数 pa=&b;pa-print();/pa=&b;pa-print();/调用类调用类调用类调用类B B的虚函数的虚函数的虚函数的虚函数 pa=&c;pa-print();/pa=&c;pa-print();/调用类调用类调用类调用类C C的虚函数的虚函数的虚函数的虚函数 12第12页,共25页,编辑于2022年,星期六class Base class Base public:public:virtual int Set(virtual int Set(int a,int bint a,int b).;class Derive:public Base class Derive:public Base public:public:int Set(int Set(int x,int yint x,int y).;class Base class Base public:public:virtual int Set(virtual int Set(int a,int bint a,int b).;class Derive:public Base class Derive:public Base public:public:int Set(int Set(int x,int y=0int x,int y=0).;int Set(int,int)int Set(int,int)是虚函数是虚函数两个两个Set()Set()函数参数不一致,是重载,不是虚函数函数参数不一致,是重载,不是虚函数13第13页,共25页,编辑于2022年,星期六关于虚函数,说明以下几点:关于虚函数,说明以下几点:关于虚函数,说明以下几点:关于虚函数,说明以下几点:1 1、当当当当在在在在基基基基类类类类中中中中把把把把成成成成员员员员函函函函数数数数定定定定义义义义为为为为虚虚虚虚函函函函数数数数后后后后,在在在在其其其其派派派派生生生生类类类类中中中中定定定定义义义义的的的的虚虚虚虚函函函函数数数数必必必必须须须须与与与与基基基基类类类类中中中中的的的的虚虚虚虚函函函函数数数数同同同同名名名名,参参参参数数数数的的的的类类类类型型型型、顺顺顺顺序序序序、参参参参数数数数的的的的个个个个数数数数必必必必须须须须一一一一一一一一对对对对应应应应,函函函函数数数数返返返返回回回回值值值值的的的的类类类类型型型型也也也也要要要要相相相相同同同同。若若若若函函函函数数数数名名名名相相相相同同同同,但但但但参参参参数数数数的的的的个个个个数数数数不不不不同同同同或或或或者者者者参参参参数数数数的的的的类类类类型型型型不不不不同同同同时时时时,则则则则属属属属于于于于函函函函数数数数的的的的重重重重载载载载,而而而而不不不不是是是是虚虚虚虚函函函函数数数数。若若若若函函函函数数数数名名名名不不不不同同同同,显然这是不同的成员函数。,显然这是不同的成员函数。,显然这是不同的成员函数。,显然这是不同的成员函数。2 2、实实实实现现现现这这这这种种种种动动动动态态态态的的的的多多多多态态态态性性性性时时时时,必必必必须须须须使使使使用用用用基基基基类类类类类类类类型型型型的的的的指指指指针针针针变变变变量量量量,并并并并使使使使该该该该指指指指针针针针指指指指向向向向不不不不同同同同的的的的派派派派生生生生类类类类对对对对象象象象,并并并并通通通通过过过过调调调调用用用用指指指指针所指向的虚函数才能实现动态的多态性。针所指向的虚函数才能实现动态的多态性。针所指向的虚函数才能实现动态的多态性。针所指向的虚函数才能实现动态的多态性。14第14页,共25页,编辑于2022年,星期六x xShow(Show()x xShow(Show()y yShow(Show()x xShow(Show()z zShow(Show()类类类类A A类类类类B B类类类类C CShow()Show()定义为虚函数定义为虚函数类类类类B B与类与类与类与类C C均为类均为类均为类均为类A A的公有派生。的公有派生。的公有派生。的公有派生。A *p;A *p;B b;B b;C c;C c;p=&b;p=&b;p-Show();p-Show();p=&c;p=&c;p-Show();p-Show();即在程序运行时,通过赋值语句实现多态性即在程序运行时,通过赋值语句实现多态性即在程序运行时,通过赋值语句实现多态性即在程序运行时,通过赋值语句实现多态性15第15页,共25页,编辑于2022年,星期六3 3、虚虚虚虚函函函函数数数数必必必必须须须须是是是是类类类类的的的的一一一一个个个个成成成成员员员员函函函函数数数数,不不不不能能能能是是是是友友友友元元元元函函函函数数数数,也不能是静态的成员函数。也不能是静态的成员函数。也不能是静态的成员函数。也不能是静态的成员函数。4 4、在在在在派派派派生生生生类类类类中中中中没没没没有有有有重重重重新新新新定定定定义义义义虚虚虚虚函函函函数数数数时时时时,与与与与一一一一般般般般的的的的成成成成员员员员函函函函数数数数一一一一样样样样,当当当当调调调调用用用用这这这这种种种种派派派派生生生生类类类类对对对对象象象象的的的的虚虚虚虚函函函函数数数数时时时时,则则则则调调调调用用用用其其其其基基基基类类类类中的虚函数中的虚函数中的虚函数中的虚函数。5 5、可可可可把把把把析析析析构构构构函函函函数数数数定定定定义义义义为为为为虚虚虚虚函函函函数数数数,但但但但是是是是,不不不不能能能能将将将将构构构构造造造造函函函函数数数数定义为虚函数定义为虚函数定义为虚函数定义为虚函数。6 6、虚虚虚虚函函函函数数数数与与与与一一一一般般般般的的的的成成成成员员员员函函函函数数数数相相相相比比比比较较较较,调调调调用用用用时时时时的的的的执执执执行行行行速速速速度度度度要要要要慢慢慢慢一一一一些些些些。为为为为了了了了实实实实现现现现多多多多态态态态性性性性,在在在在每每每每一一一一个个个个派派派派生生生生类类类类中中中中均均均均要要要要保保保保存存存存相相相相应应应应虚虚虚虚函函函函数数数数的的的的入入入入口口口口地地地地址址址址表表表表,函函函函数数数数的的的的调调调调用用用用机机机机制制制制也也也也是是是是间间间间接接接接实实实实现现现现的的的的。因因因因此此此此,除除除除了了了了要要要要编编编编写写写写一一一一些些些些通通通通用用用用的的的的程程程程序序序序,并并并并一一一一定定定定要要要要使使使使用用用用虚虚虚虚函函函函数数数数才才才才能能能能完完完完成成成成其其其其功能的情况之外,通常不必使用虚函数。功能的情况之外,通常不必使用虚函数。功能的情况之外,通常不必使用虚函数。功能的情况之外,通常不必使用虚函数。16第16页,共25页,编辑于2022年,星期六7 7、一一一一个个个个函函函函数数数数如如如如果果果果被被被被定定定定义义义义成成成成虚虚虚虚函函函函数数数数,则则则则不不不不管管管管经经经经历历历历多多多多少少少少次次次次派派派派生,仍将保持其虚特性,以实现生,仍将保持其虚特性,以实现生,仍将保持其虚特性,以实现生,仍将保持其虚特性,以实现“一个接口,多个形态一个接口,多个形态一个接口,多个形态一个接口,多个形态”。虚函数的访问虚函数的访问虚函数的访问虚函数的访问用基类指针访问与用对象名访问用基类指针访问与用对象名访问用基类指针访问与用对象名访问用基类指针访问与用对象名访问用基类指针访问虚函数时,指向其实际派生类对象重新用基类指针访问虚函数时,指向其实际派生类对象重新用基类指针访问虚函数时,指向其实际派生类对象重新用基类指针访问虚函数时,指向其实际派生类对象重新定义的函数。实现动态约束。定义的函数。实现动态约束。定义的函数。实现动态约束。定义的函数。实现动态约束。通过一个通过一个通过一个通过一个对象名对象名对象名对象名访问时,只能静态约束。即由编译器在访问时,只能静态约束。即由编译器在访问时,只能静态约束。即由编译器在访问时,只能静态约束。即由编译器在编译的时候决定调用哪个函数。编译的时候决定调用哪个函数。编译的时候决定调用哪个函数。编译的时候决定调用哪个函数。17第17页,共25页,编辑于2022年,星期六class Point float x,y;class Point float x,y;public:public:Point()Point()Point(float i,float j)x=i;y=j;Point(float i,float j)x=i;y=j;virtualvirtual float area(void)return 0.0;/float area(void)return 0.0;/声明为虚函数声明为虚函数声明为虚函数声明为虚函数;const float Pi=3.14159;const float Pi=3.14159;class Circle:public Point /class Circle:public Point /类类类类PointPoint的派生类的派生类的派生类的派生类float radius;float radius;public:public:Circle(float r)radius=r;Circle(float r)radius=r;float area(void)return Pi*radius*radius;/float area(void)return Pi*radius*radius;/虚函数再定义虚函数再定义虚函数再定义虚函数再定义;void main(void)void main(void)Circle c(5.4321);Circle c(5.4321);coutc.area()endl;coutc.area()endl;coutc.Point:area()endl;coutc.Point:area()endl;coutc.Circle:area()endl;coutc.Circle:area()endl;输出:输出:输出:输出:92.701192.70110 092.701192.7011可见,利用对象名进行调用与一般非虚函数没有区别。可见,利用对象名进行调用与一般非虚函数没有区别。可见,利用对象名进行调用与一般非虚函数没有区别。可见,利用对象名进行调用与一般非虚函数没有区别。用对象名调用用对象名调用area()area()18第18页,共25页,编辑于2022年,星期六class base0 class base0 public:void v(void)coutbase0n;public:void v(void)coutbase0n;class base1:public base0 class base1:public base0 public:virtual void v(void)coutbase1n;public:virtual void v(void)coutbase1n;class A1:public base1 class A1:public base1 public:void v()coutA1n;public:void v()coutA1n;class A2:public A1 class A2:public A1 public:void v(void)coutA2n;public:void v(void)coutA2n;class B1:private base1 class B1:private base1 public:void v(void)coutB1n;public:void v(void)coutB1n;class B2:public B1 class B2:public B1 public:void v(void)coutB2n;public:void v(void)coutv();(pb=&a1)-v();A2 a2;A2 a2;(pb=&a2)-v();(pb=&a2)-v();B1 b1;B1 b1;(pb=&b1)-v();(pb=&b1)-v();B2 b2;B2 b2;(pb=&b2)-v();(pb=&b2)-v();base0base0base0base0私有派生,在类外不私有派生,在类外不能调用基类函数能调用基类函数19第19页,共25页,编辑于2022年,星期六class base0 class base0 public:void v(void)coutbase0n;public:void v(void)coutbase0n;class base1:public base0 class base1:public base0 public:virtual void v(void)coutbase1n;public:virtual void v(void)coutbase1n;class A1:public base1 class A1:public base1 public:void v()coutA1n;public:void v()coutA1n;class A2:public A1 class A2:public A1 public:void v(void)coutA2n;public:void v(void)coutA2n;class B1:private base1 class B1:private base1 public:void v(void)coutB1n;public:void v(void)coutB1n;class B2:public B1 class B2:public B1 public:void v(void)coutB2n;public:void v(void)coutv();(pb=&a1)-v();A2 a2;A2 a2;(pb=&a2)-v();(pb=&a2)-v();A1A1A2A2这一讲到此结束。这一讲到此结束。这一讲到此结束。这一讲到此结束。20第20页,共25页,编辑于2022年,星期六6.4 纯虚函数与抽象类纯虚函数与抽象类在在在在基基基基类类类类中中中中不不不不对对对对虚虚虚虚函函函函数数数数给给给给出出出出有有有有意意意意义义义义的的的的实实实实现现现现,它它它它只只只只是是是是在在在在派派派派生生生生类类类类中中中中有有有有具具具具体体体体的的的的意意意意义义义义。这这这这时时时时基基基基类类类类中中中中的的的的虚虚虚虚函函函函数数数数只只只只是是是是一一一一个个个个入入入入口口口口,具具具具体体体体的的的的目目目目的的的的地地地地由由由由不不不不同同同同的的的的派派派派生生生生类类类类中中中中的的的的对对对对象象象象决决决决定定定定。这这这这个个个个虚虚虚虚函函函函数数数数称称称称为为为为纯纯纯纯虚虚虚虚函函函函数数数数。class class virtual virtual ()=0=0;.;21第21页,共25页,编辑于2022年,星期六class A class A protected:int x;protected:int x;public:public:A()x=1000;A()x=1000;virtual void print()=0;/virtual void print()=0;/定义纯虚函数定义纯虚函数定义纯虚函数定义纯虚函数;class B:public A /class B:public A /派生类派生类派生类派生类private:int y;private:int y;public:public:B()y=2000;B()y=2000;void print()cout y=yn;/void print()cout y=yn;/重新定义纯虚函数重新定义纯虚函数重新定义纯虚函数重新定义纯虚函数;class C:public A /class C:public A /派生类派生类派生类派生类int z;int z;public:public:C()z=3000;C()z=3000;void print()cout z=zn;/void print()cout z=zprint();pa-print();pa=&c;pa=&c;pa-print();pa-print();A a;A a;pa=&a;pa=&a;pa-print();pa-print();y=2000y=2000z=3000z=3000抽象类抽象类不能定义抽象类的对象不能定义抽象类的对象22第22页,共25页,编辑于2022年,星期六1 1、在定义纯虚函数时,不能定义虚函数的实现部分。、在定义纯虚函数时,不能定义虚函数的实现部分。、在定义纯虚函数时,不能定义虚函数的实现部分。、在定义纯虚函数时,不能定义虚函数的实现部分。2 2、把把把把函函函函数数数数名名名名赋赋赋赋于于于于0 0,本本本本质质质质上上上上是是是是将将将将指指指指向向向向函函函函数数数数体体体体的的的的指指指指针针针针值值值值赋赋赋赋为为为为初初初初值值值值0 0。与与与与定定定定义义义义空空空空函函函函数数数数不不不不一一一一样样样样,空空空空函函函函数数数数的的的的函函函函数数数数体体体体为为为为空空空空,即即即即调调调调用用用用该该该该函函函函数数数数时时时时,不不不不执执执执行行行行任任任任何何何何动动动动作作作作。在在在在没没没没有有有有重重重重新新新新定定定定义义义义这这这这种种种种纯纯纯纯虚虚虚虚函函函函数数数数之之之之前前前前,是是是是不能调用这种函数的。不能调用这种函数的。不能调用这种函数的。不能调用这种函数的。3 3、把把把把至至至至少少少少包包包包含含含含一一一一个个个个纯纯纯纯虚虚虚虚函函函函数数数数的的的的类类类类,称称称称为为为为抽抽抽抽象象象象类类类类。这这这这种种种种类类类类只能作为派生类的基类,不能用来说明这种类的对象只能作为派生类的基类,不能用来说明这种类的对象只能作为派生类的基类,不能用来说明这种类的对象只能作为派生类的基类,不能用来说明这种类的对象。其其其其理理理理由由由由是是是是明明明明显显显显的的的的:因因因因为为为为纯纯纯纯虚虚虚虚函函函函数数数数没没没没有有有有实实实实现现现现部部部部分分分分,所所所所以以以以不不不不能能能能产产产产生生生生对对对对象象象象。但但但但可可可可以以以以定定定定义义义义指指指指向向向向抽抽抽抽象象象象类类类类的的的的指指指指针针针针,即即即即指指指指向向向向这这这这种种种种基基基基类类类类对对对对象象象象的的的的指指指指针针针针。当当当当用用用用这这这这种种种种基基基基类类类类指指指指针针针针指指指指向向向向其其其其派派派派生生生生类类类类的的的的对对对对象象象象时时时时,必须在派生类中必须在派生类中必须在派生类中必须在派生类中重载重载重载重载纯虚函数,否则会产生程序的运行错误。纯虚函数,否则会产生程序的运行错误。纯虚函数,否则会产生程序的运行错误。纯虚函数,否则会产生程序的运行错误。23第23页,共25页,编辑于2022年,星期六4 4、在在在在以以以以抽抽抽抽象象象象类类类类作作作作为为为为基基基基类类类类的的的的派派派派生生生生类类类类中中中中必必必必须须须须有有有有纯纯纯纯虚虚虚虚函函函函数数数数的的的的实实实实现现现现部部部部分分分分,即即即即必必必必须须须须有有有有重重重重载载载载纯纯纯纯虚虚虚虚函函函函数数数数的的的的函函函函数数数数体体体体。否否否否则则则则,这这这这样的派生类也是不能产生对象的。样的派生类也是不能产生对象的。样的派生类也是不能产生对象的。样的派生类也是不能产生对象的。综综综综上上上上所所所所述述述述,可可可可把把把把纯纯纯纯虚虚虚虚函函函函数数数数归归归归结结结结为为为为:抽抽抽抽象象象象类类类类的的的的唯唯唯唯一一一一用用用用途途途途是是是是为为为为派派派派生生生生类类类类提提提提供供供供基基基基类类类类,纯纯纯纯虚虚虚虚函函函函数数数数的的的的作作作作用用用用是是是是作作作作为为为为派派派派生生生生类类类类中中中中的的的的成成成成员函数的基础,并实现动态多态性。员函数的基础,并实现动态多态性。员函数的基础,并实现动态多态性。员函数的基础,并实现动态多态性。例例例例6.46.4 虚函数和抽象类的应用。虚函数和抽象类的应用。虚函数和抽象类的应用。虚函数和抽象类的应用。24第24页,共25页,编辑于2022年,星期六作作 业业P219 4 5第16周星期三第3、4节课补上第2周星期三的3、4节课!25第25页,共25页,编辑于2022年,星期六