C学习第6 多态性与虚函数_第1页
C学习第6 多态性与虚函数_第2页
C学习第6 多态性与虚函数_第3页
C学习第6 多态性与虚函数_第4页
C学习第6 多态性与虚函数_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1第第6章章 多态性与虚函数多态性与虚函数 2 一、虚函数一、虚函数多态性:多态性:调用同一个函数名,但可以根据需要实调用同一个函数名,但可以根据需要实现不同的功能。现不同的功能。多态性是面向对象的程序设计的关键技术。多态性是面向对象的程序设计的关键技术。编译时的多态性(函数重载)编译时的多态性(函数重载)运行时的多态性运行时的多态性(虚函数)(虚函数)多态性多态性运行时的多态性是指在程序执行之前,根据函数名和运行时的多态性是指在程序执行之前,根据函数名和参数无法确定应该调用哪一个函数,必须在程序的执参数无法确定应该调用哪一个函数,必须在程序的执行过程中,行过程中,根据具体的执行情况来动态地确

2、定。根据具体的执行情况来动态地确定。3可以将一个派生类对象的地址赋给基类的指针变量可以将一个派生类对象的地址赋给基类的指针变量。基类对象基类对象派生类对象派生类对象base b;derive d;base *basep;basepbasep=&b;basepbasep = &d;basep只能引用从基只能引用从基类继承来的成员。类继承来的成员。xshow()xshow()yshow()basep -show();basep-show()基类指针基类指针派生类对象派生类对象基类对象基类对象4void main(void) circle c(5.4321); point *pp;

3、/基类指针基类指针 pp=&c; /将派生类对象的地址赋给基类指针将派生类对象的地址赋给基类指针 coutarea ( )show()base *basep;basep=&b;basep = &d;即指向派生类新增的成员函数即指向派生类新增的成员函数,?basep-show()67void main(void) circle c(5.4321); point *pp; /基类指针基类指针 pp=&c; /将派生类对象的地址赋给基类指针将派生类对象的地址赋给基类指针 coutendl; class pointfloat x,y;public:point()poin

4、t(float i, float j)x=i;y=j;virtual ;const float pi=3.14159;class circle:public pointfloat radius;public:circle(float r)radius=r;8二、虚函数的定义和使用二、虚函数的定义和使用 可以在程序运行时通过调用相同的函数名而实可以在程序运行时通过调用相同的函数名而实现不同功能的函数称为现不同功能的函数称为虚函数虚函数。定义格式为:。定义格式为: virtual funcname(); 一旦把基类的成员函数定义为虚函数,由基类一旦把基类的成员函数定义为虚函数,由基类所派生出来的所

5、有派生类中,该函数均保持虚函所派生出来的所有派生类中,该函数均保持虚函数的特性。数的特性。 9虚函数是用关键字虚函数是用关键字virtual修饰的某基类中的修饰的某基类中的protected或或public成员函数。它可以在派生类中成员函数。它可以在派生类中重新定义,以形成不同版本。重新定义,以形成不同版本。只有在程序的执只有在程序的执行过程中,依据指针具体指向哪个类对象,或行过程中,依据指针具体指向哪个类对象,或依据引用哪个类对象,才能确定激活哪一个版依据引用哪个类对象,才能确定激活哪一个版本,实现动态关联本,实现动态关联。10void main(void ) a a, *pa; b b;

6、c c; a.print(); b.print();c.print(); /以上为静态关联以上为静态关联 pa=&a; pa-print();/调用类调用类a的虚函数的虚函数 pa=&b; pa-print();/调用类调用类b的虚函数的虚函数 pa=&c; pa-print();/调用类调用类c的虚函数的虚函数class aprotected:int x;public: a( )x =1000; virtual void print( ) /虚函数虚函数 cout “x=”xt;class b:public a int y;public: b( ) y=2000;vo

7、id print( ) /派生虚函数派生虚函数 cout “y=”yt; ;class c:public a int z;public: c( )z=3000;void print( ) /派生虚函数派生虚函数 cout “z=”zshow();即在程序运行时,即在程序运行时,通过赋值语句实通过赋值语句实现多态性现多态性xshow()xshow()yshow()xshow()zshow()类类a类类b:public a 类类c:public ashow()定义为虚函数定义为虚函数143 3、虚函数必须是类的一个成员函数,不能是友虚函数必须是类的一个成员函数,不能是友元函数,也不能是静态的成员函

8、数。元函数,也不能是静态的成员函数。4 4、可把析构函数定义为虚函数,但是,不能将可把析构函数定义为虚函数,但是,不能将构造函数定义为虚函数构造函数定义为虚函数。5 5、一个函数如果被定义成虚函数,则不管经历、一个函数如果被定义成虚函数,则不管经历多少次派生,仍将保持其虚特性,以实现多少次派生,仍将保持其虚特性,以实现“一个一个接口,多个形态接口,多个形态”。156、虚函数与一般的成员函数相比较,、虚函数与一般的成员函数相比较,。为了实现多态性,在每一。为了实现多态性,在每一个派生类中均要保存相应虚函数的入口地址表,个派生类中均要保存相应虚函数的入口地址表,函数的调用机制也是间接实现的。因此,

9、除了函数的调用机制也是间接实现的。因此,除了要编写一些通用的程序,并一定要使用虚函数要编写一些通用的程序,并一定要使用虚函数才能完成其功能要求外,才能完成其功能要求外,16三、虚函数的访问三、虚函数的访问用基指针访问与用对象名访问用基指针访问与用对象名访问 用基指针访问虚函数时,指向其实际派用基指针访问虚函数时,指向其实际派生类对象重新定义的函数。实现动态关联。生类对象重新定义的函数。实现动态关联。 通过一个通过一个对象名对象名访问时,只能静态关联。访问时,只能静态关联。即由编译器在编译的时候决定调用哪个函数。即由编译器在编译的时候决定调用哪个函数。17void main(void) circ

10、le c(5.4321); point *pp; /基类指针基类指针 pp=&c; /将派生类对象的地址赋给基类指针将派生类对象的地址赋给基类指针 coutarea ( )endl; coutc.area()endl; coutc.point:area()endl; cout point:area ()endl;class pointfloat x,y;public:point()point(float i, float j)x=i;y=j;virtual float area(void)return 0.0;const float pi=3.14159;class circle:pu

11、blic pointfloat radius;public:circle(float r)radius=r;float area(void) return pi*radius*radius;声明为虚函数声明为虚函数虚函数再定义虚函数再定义利用对象名进行调用与一利用对象名进行调用与一般非虚函数没有区别。般非虚函数没有区别。输出:输出:92.7011 92.70110018四、纯虚函数四、纯虚函数 在基类中不对虚函数给出有意义的实现在基类中不对虚函数给出有意义的实现,它它只是在派生类中有具体的意义。这时基类中的虚只是在派生类中有具体的意义。这时基类中的虚函数只是一个入口,具体的目的地由不同的派生函

12、数只是一个入口,具体的目的地由不同的派生类中的对象决定。这个虚函数称为类中的对象决定。这个虚函数称为纯虚函数纯虚函数。 包含纯虚函数的类为包含纯虚函数的类为抽象类抽象类。class virtual ()=0;.;19void main(void ) a *pa; b b; c c;b.print();c.print(); pa=&b; pa-print();/调用类调用类b的虚函数的虚函数 pa=&c; pa-print();/调用类调用类c的虚函数的虚函数 a a; pa=&a; pa-print();/调用类调用类a的虚函数的虚函数?class aprotected

13、:int x;public: a( )x =1000; virtual void print( )=0 ;/纯虚函数纯虚函数;class b:public a int y;public: b( ) y=2000;void print( ) /再定义纯虚函数再定义纯虚函数 cout “y=”yt; ;class c:public a int z;public: c( )z=3000;void print( ) /再定义纯虚函再定义纯虚函数数 cout “z=”zn;不能定义抽象类的对象不能定义抽象类的对象201、在定义纯虚函数时,不能定义虚函数的实现、在定义纯虚函数时,不能定义虚函数的实现部分。

14、部分。2、把函数名赋于、把函数名赋于0,本质上是将指向函数体的,本质上是将指向函数体的指针值赋为初值指针值赋为初值0。与定义空函数不一样,空函。与定义空函数不一样,空函数的函数体为空,即调用该函数时,不执行任数的函数体为空,即调用该函数时,不执行任何动作。何动作。在没有重新定义这种纯虚函数之前,在没有重新定义这种纯虚函数之前,是不能调用这种函数的。是不能调用这种函数的。213、把至少包含一个纯虚函数的类,称为抽象把至少包含一个纯虚函数的类,称为抽象类。这种类只能作为派生类的基类,不能用来类。这种类只能作为派生类的基类,不能用来说明这种类的对象说明这种类的对象。其理由是明显的:因为虚函数没有实现部分,其理由是明显的:因为虚函数没有实现部分,所以不能产生对象。但可以定义指向抽象类的所以不能产生对象。但可以定义指向抽象类的指针,即指向这种基类的指针。当用这种基类指针,即指向这种基类的指针。当用这种基类指针指向其派生类的对象时,指针指向其派生类的对象时,必须在派生类中必须在派生类中重载重载纯虚函数,否则会产生程序的运行错误。纯虚函数,否则会产生程序的运行错误。224、在以抽象类作为基类的派生类中必须有纯在以抽象类作为基类的派生类中必须有纯虚函

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论