扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这篇文章将为大家详细讲解有关关于C++虚函数工作原理的介绍,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
成都创新互联公司致力于互联网品牌建设与网络营销,包括成都网站建设、成都做网站、SEO优化、网络推广、整站优化营销策划推广、电子商务、移动互联网营销等。成都创新互联公司为不同类型的客户提供良好的互联网应用定制及解决方案,成都创新互联公司核心团队10年专注互联网开发,积累了丰富的网站经验,为广大企业客户提供一站式企业网站建设服务,在网站建设行业内树立了良好口碑。静态绑定与动态绑定
讨论静态绑定与动态绑定,首先需要理解的是绑定,何为绑定?函数调用与函数本身的关联,以及成员访问与变量内存地址间的关系,称为绑定。 理解了绑定后再理解静态与动态。
C++中动态绑定
在C++中动态绑定是通过虚函数实现的,是多态实现的具体形式。而虚函数是通过虚函数表实现的。这个表中记录了虚函数的地址,解决继承、覆盖的问题,保证动态绑定时能够根据对象的实际类型调用正确的函数。这个虚函数表在什么地方呢?C++标准规格说明书中说到,编译器必须要保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证正确取到虚函数的偏移量)。也就是说,我们可以通过对象实例的地址得到这张虚函数表,然后可以遍历其中的函数指针,并调用相应的函数。
虚函数的工作原理
要想弄明白动态绑定,就必须弄懂虚函数的工作原理。C++中虚函数的实现一般是通过虚函数表实现的(C++规范中没有规定具体用哪种方法,但大部分的编译器厂商都选择此方法)。类的虚函数表是一块连续的内存,每个内存单元中记录一个JMP指令的地址。编译器会为每个有虚函数的类创建一个虚函数表,该虚函数表将被该类的所有对象共享。 类的每个虚成员占据虚函数表中的一行。如果类中有N个虚函数,那么其虚函数表将有N*4字节的大小。
虚函数(virtual)是通过虚函数表来实现的,在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其真实反映实际的函数。这样,在有虚函数的类的实例中分配了指向这个表的指针的内存(位于对象实例的最前面),所以,当用父类的指针来操作一个子类的时候,这张虚函数表就显得尤为重要,指明了实际所应调用的函数。它是如何指明的呢?后面会讲到。
JMP指令是汇编语言中的无条件跳转指令,无条件跳转指令可转到内存中任何程序段。转移地址可在指令中给出,也可以在寄存器中给出,或在储存器中指出。
首先我们定义一个带有虚函数的基类
class Base { public: virtual void fun1(){ cout<<"base fun1!\n"; } virtual void fun2(){ cout<<"base fun2!\n"; } virtual void fun3(){ cout<<"base fun3!\n"; } int a; };
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流