第八章的 多态性和虚函数.pptVIP

  1. 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第八章的 多态性和虚函数

第八章 多态性和虚函数 主讲:冯传胜 Email:fcs@ 8.1 多态性 8.1.1 静态联编中的赋值兼容性及名字支配规律 8.1.2 动态联编的多态性 8.2 虚函数 8.2.1 虚函数的定义 8.2.2 虚函数实现多态性的条件 8.2.3 构造函数和析构函数调用虚函数 8.2.4 纯虚函数和抽象类 8.3 多重继承与虚函数 8.4 类成员函数的指针与多态性 8.1 多态性 静态联编所支持的多态性称为编译时的多态性。当调用重载函数时,编译器可以根据调用时所使用的实参在编译时就确定下来应调用哪个函数。 动态联编所支持的多态性称为运行时的多态性,由虚函数支持。即对虚函数的调用使用动态联编。 8.1.1 静态联编中的赋值兼容性及名字支配规律 派生一个类的原因并非总是为了添加新的数据成员或成员函数,有时是为了重新定义基类的成员函数。 例8.1:分析下面程序的输出结果。 ① ② 编译器在编译时,从调用的对象上就可知是调用的哪个函数 ③ ④ 根据赋值兼容性规则,它调用的是应该是基类的area函数,即Point::area()。 ⑤ ⑥ 同样根据赋值兼容性规则,它调用的是应该是基类的area函数,即Point::area()。 从上图中可以看出:在对象的内存中只包含数据成员,而没有成员函数的信息。这说明成员函数的地址翻译过程与其对象的内存地址无关。编译器只根据数据类型翻译成员函数的地址并判断其调用的合法性。 如: Point *p; p=a;//或 p=c; p-area( )总是指Point类的area()函数 8.1.2 动态联编的多态性 如果采用编译器动态联编,编译器只检查合法性,如 Circle c; Point *p=c; //编译器检查合理性 p-area(); //在程序运行时编译 如果希望“p-area()”调用的函数是Circle类的成员函数,则需要将Point类中的area函数声明成虚函数。 虚函数:用关键字virtual声明的函数。如 virtual double area() {return(0.0);} 编译器编译含有虚函数的类时,将为它建立一个虚函数表,表中每一个元素都指向一个虚函数的地址。 编译器也为类增加一个数据成员,这个数据成员是一个指向该虚函数表的指针,通常称为“vptr”。如图 如果派生类没有重写这个area()函数,则派生类的虚函数表里元素所指向的地址就是基类Point的虚函数area()的地址,即派生类仅继承基类的虚函数。 如果将Circle类中的area()函数改写成 virtual double area(){return PI*r*r;} 则虚函数表中地址为Circle::area()的地址 虚函数的地址翻译取决于对象的内存地址。编译器为含有虚函数类的对象首先建立一个入口地址,这个地址用来存入指向虚函数表的指针vptr,然后按照类中虚函数的声明次序,一一填入函数指针。当调用虚函数时,先通过vptr找到虚函数表,然后再找出虚函数的真正地址。 派生类能继承基类的虚函数表,而且只要是和基类同名(参数也相同)的成员函数,无论是否使用virtual声明,它们都自动成为虚函数。如果派生类没有改写继承基类的虚函数,则函数指针调用基类的虚函数。如果派生类改写了基类的虚函数,编译器将重新为派生类的虚函数建立地址,函数指针会调用改写过的虚函数。 虚函数调用规则:根据当前对象,优先调用对象本身的虚成员函数。 重新分析语句:p-area(); 8.2 虚函数 一旦基类定义了虚函数,该基类的派生类中的同名函数也自动成为虚函数。 8.2.1 虚函数的定义 虚函数只能是类中的一个成员函数,但不能是静态成员,关键字virtual用于类中该函数的声明中。如: class A { public: virtual void fun(); //声明虚函数 } void A::fun(){…//函数体} //定义虚函数 当在派生类中定义一个同名的成员函数时,只要该成员函数的参数个数和相应类型以及它的返回类型与基类中同名的虚函数完全一样,则该函数无论是否使用virtual,它都将成为一个虚函数。 8.2.2 虚函数实现多态性的条件 关键字virtual指示编译器对调用虚函数进行动态联编。 这种多态性是程序运行到需要的语句处才动态确定的,所以称为运行时的多态性。 使用虚函数并不一定产生多态性,也不一定使用动态联编。如,在调用中对虚函数使用成员名限定,可以强制C++对该函数的调用使用静态联编。 产生运行时的多态性有如下三个前提: 类之间的继承关系满足赋值兼容性规则 改写了同名虚函数 根据赋值兼容性规则使用指针或引用 第一种情况:按赋值兼容性规则使用基类指针或引用访问虚函数(如前例) 第二种情况:把指

文档评论(0)

liwenhua00 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档