- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
派生类中的虚函数 虚函数是类成员函数(class member function); 在派生类(derived class)中对虚函数的实现重新定义称之为覆盖(override) 虚函数的“身份”在继承之间能被持续传递下去 再次运行,结果… #include iostream using namespace std; enum note { middleC, Csharp, Eflat };. class Instrument { public: virtual void play(note) const { cout Instrument::play endl; } }; // Wind objects are Instruments // because they have the same interface: class Wind : public Instrument { public: // Redefine interface function: void play(note) const { cout Wind::play endl; } }; void tune(Instrument i) { // ... i.play(middleC); } int main() { Wind flute; tune(flute); // Upcasting return 0; } 这次结果是我们希望的结果! 我们引入了虚函数机制,导致了这样的结果。 “神奇的” 执行方式 ? 以基类指针运行虚函数,程序就能执行我们所期望的正确的派生类的函数体,虚函数为什么会有这样“神奇的”运行机制呢? 通过继承而相关的不同类,他们的对象能够对同一个函数作出不同的响应.这样“神奇的” 多态性是怎样实现的呢? 静态绑定与动态绑定 绑定(binding) 程序自身彼此关联的过程,确定程序中的操作调用与执行该操作的代码间的关系。 静态绑定(early binding) 绑定过程出现在编译阶段,用对象名或者类名来限定要调用的函数。 动态绑定(dynamic/later binding) 绑定过程工作在程序运行时执行,在程序运行时才确定将要调用的函数。 “神奇的” 执行方式 ——动态绑定 C++的虚函数在运行时正是通过动态绑定实现多态机制的。 动态绑定是如何实现的呢? 动态绑定是通过编译器运用虚函数表VTBL和虚表指针VPTR而实现,在运行时通过动态查询实现对正确函数体的绑定。 VTBL 编译器会为声明了虚函数的类建立一个虚函数表。 VTBL实际上是一个函数指针数组,每个虚函数占用这个数组的一个入口(slot)。 一个类只有一个VTBL,不管它有多少个实例。 派生类有自己的VTBL,但是派生类的VTBL与基类的VTBL有相同的函数排列顺序,同名的虚函数被放在两个数组的相同位置上。 VPTR 在创建类实例的时候,编译器还会在每个实例的内存布局中增加一个VPTR指针,该指针指向本类的VTBL。 最后,是动态联编 在调用此类的构造函数时,在类的构造函数中,编译器会隐含执行VPTR与VTBL的关联代码,将VPTR指向对应的VTBL。这就将类与此类的VTBL联系了起来。 ?在调用类的构造函数时,指向基类的指针此时已经变成指向具体的类的this指针,依靠此this指针,进一步得到正确的VPTR,即可得到正确的VTBL,从而实现了多态性。在此时才能真正与函数体进行连接,这就是动态联编。 一个更大的例子… #include iostream using namespace std; enum note { middleC, Csharp, Cflat }; // Etc. class Instrument { public: virtual void play(note) const { cout Instrument::play endl; } virtual char* what() const { return Instrument; } virtual void adjust(int) {} }; class Wind : public Instrument { public: void play(note) const { cout Wind::play endl; } char* what() const { return Wind; } void adjust(int) {} }; class Percussion : public Instrument { public: void play(n
文档评论(0)