第六章 C++编程之对虚函数理解.docxVIP

  1. 1、本文档共8页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C++编程之理解虚函数本文目的了解虚函数的定义、应用场合、内部实现机制以及注意事项。什么是虚函数?缺省情况下,类的成员函数是非虚拟的(nonvirtual)。当一个成员函数为非虚拟的时候,通过一个类对象(指针或引用)而被调用的该成员函数,就是该类对象的静态类型中定义的成员函数。当类的成员函数被virtual关键字修饰时,该函数就是虚函数。当成员函数是虚函数时,通过一个类对象(指针或引用)而被调用的该成员函数,是在该类对象的动态类型中被定义的成员函数。普通函数虚函数class 类名{public:函数说明;};class 类名{public:virtual 函数说明;};对于动态类型的理解:虚函数允许派生类取代基类所提供的实现。为什么使用虚函数?C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。简单的例子://基类——Aclass A{public:virtualvoid describe(){cout This is A. endl;}};//类B——派生于基类Aclass B : public A{public:virtualvoid describe(){cout This is B. endl;}};int main(int argc, char* argv[]){A *p = new A();p-describe();delete p;p = new B();p-describe();delete p;return 0;}输出结果:什么时候使用虚函数?在实际开发过程中,当我们使用一些类库或框架时,这些类库和框架是事先定义或设计好的,我们不能直接修改类库或框架的代码,这样我们只能派生类库或框架中的类来覆盖一些成员函数以实现我们的功能,但这些成员函数是由类库或框架来调用的,这种情况下,使用虚函数是很好的解决办法。追根究底——虚函数的实现机制虚函数表C++规定了虚函数的行为,但将实现方法留给了编译器作者。不需要知道实现方法就可以使用虚函数,但了解虚函数的工作原理有助于更好地理解概念。例子:计算类的大小是多少?class A{public:void describe(){cout This is A. endl;}};int main(int argc, char* argv[]){A a;cout 求a对象的大小: sizeof(a) endl;return 0;}输出结果:例子:计算类的大小是多少?class A{public:void describe(){cout This is A. endl;}//虚函数virtualvoid func1(){cout Call fun1 in Class B. endl;}};int main(int argc, char* argv[]){A a;cout 求a对象的大小: sizeof(a) endl;return 0;}输出结果:对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。通常,编译器处理虚函数的方法是:给每个对象添加一个隐藏成员。隐藏成员中包含了一个指向函数地址数组的指针。这种数组成为虚函数表(virtual function table, vtbl)。虚函数表中存储了为类对象进行声明的虚函数的地址。例如,基类对象包含一个指针,该指针指向基类中所有虚函数的地址表。派生类对象将包含一个指向独立地址表的指针。如果派生类提供了虚函数的新定义,该虚函数表将保存新函数的地址;如果派生类没有重新定义虚函数,该vtbl将保存函数原始版本的地址。如果派生类定义了新的虚函数,则该函数的地址也将被添加到vtbl中。注意,无论类中包含的虚函数是1个还是多个,都只需要在对象中添加1个地址成员,只是表的大小不同而已。这里我们着重看一下这张虚函数表。C++的编译器应该是保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——如果有多层继承或是多重继承的情况下)。 这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。类Class虚函数表虚函数表地址Vfptr(1)Vfptr(2)……Vfptr(n)成员变量成员变量……虚

文档评论(0)

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

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

1亿VIP精品文档

相关文档