在面试过程中C的多态实现机制经常会被面试官问道。大家清楚多态到底该如何实现吗下面小编抽空给大家介绍下多态的实现机制。1. 用virtual关键字申明的函数叫做虚函数虚函数肯定是类的成员函数。2. 存在虚函数的类都有一个一维的虚函数表叫做虚表。类的对象有一个指向虚表开始的虚指针。虚表是和类对应的虚表指针是和对象对应的。3. 多态性是一个接口多种实现是面向对象的核心。分为类的多态性和函数的多态性。4. 多态用虚函数来实现结合动态绑定。5. 纯虚函数是虚函数再加上 0。6. 抽象类是指包括至少一个纯虚函数的类。多态的简单介绍一般来说多态分为两种静态多态和动态多态。静态多态也称编译时多态主要包括模板和重载。而动态多态则是通过类的继承和虚函数来实现当基类和子类拥有同名同参同返回的方法且该方法声明为虚方法当基类对象指针引用指向的是派生类的对象的时候基类对象指针引用在调用基类的方法实际上调用的是派生类方法。这就是动态多态。静态多态的实现静态多态靠编译器来实现简单来说就是编译器对原来的函数名进行修饰在c语言中函数无法重载是因为c编译器在修饰函数时只是简单的在函数名前加上下划线_ 。而c编译器不同它根据函数的类型个数来对函数名进行修饰这就使得函数可以重载同理模板也是可以实现的针对不同类型的实参来产生对应的特化的函数通过增加修饰使得不同的类型参数的函数得以区分。以下段程序为例123456789101112131415161718#include iostreamusingnamespacestd;templatetypenameT1,typenameT2intfun(T1 t1, T2 t2){}intfoofun(){}intfoofun(int){}intfoofun(int,float){}intfoofun(int,float,double){}intmain(intargc,char*argv[]){fun(1, 2);fun(1, 1.1);foofun();foofun(1);foofun(1, 1.1);foofun(1, 1.1, 1.11);return0;}经过编译之后只选取main函数部分来看可以发现调用的函数名均发生了变化都加了相应的修饰使得调用的函数是不一样的静态多态就是如此。动态多态的实现声明一个类时如果类中有虚方法则自动在类中增加一个虚函数指针该指针指向的是一个虚函数表虚函数表中存着每个虚函数真正对应的函数地址。动态多态采用一种延迟绑定技术普通的函数调用在编译期间就已经确定了调用的函数的地址所以无论怎样调用总是那个函数但是拥有虚函数的类在调用虚函数时首先去查虚函数表然后在确定调用的是哪一个函数所以调用的函数是在运行时才会确定的。在声明基类对象时虚函数表中绑定的就是基类的方法的地址。在声明派生类对象时虚函数表中绑定的就是派生类的方法。在对象被创建之后(以指针为例)无论是基类指针还是派生类指针指向这个对象虚函数表是不会改变的。以下段程序为例123456789101112131415161718192021222324252627282930#include iostreamusingnamespacestd;classBase{public:virtualvoidfun(){cout this is base fun endl;}};classDerived :publicBase{public:voidfun(){cout this is Derived fun endl;}};intmain(intargc,char*argv[]){Base b1;Derived d1;Base *pb d1;Derived *pd (Derived *)b1;b1.fun();pd-fun();d1.fun();pb-fun();return0;}运行结果如下从结果可以看出当一个对象被创建之后在调用虚函数的时候无论是派生类指针还是基类指针指向这个对象调用虚函数的结果是一样的。因为虚函数表是不变。当然有可能在多继承中会有多个虚函数表从而导致函数调用时调用不同的虚函数表这里不做考虑。