实现多态有两种方法: 1、覆盖 *********** 覆盖是指子类重新定义父类的虚函数的做法。
2、重载 *********** 重载是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。
分析: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 重载是在同一个类中相同的返回类型和方法名,但是参数的个数和类型可以不同;而覆盖是在不同的类中。 其实,重载的概念并不属于面向对象编程,重载的实现是:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数。 比如有下面两个同名函数:
那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。
对于这两个函数的调用,在编译期间就已经确定了,是静态的,称为早期联编。因此重载和多态无关。 真正和多态相关的是覆盖。当子类重新定义了父类的虚函数后,父类指针根据赋值给它的不同的子类指针,动态的调用属于子类的该函数,这样函数调用在编译期间是无法确定的,这样的函数地址在运行期间绑定称为动态联编。 不要犯傻,如果它不是晚绑定,它就不是多态。
多态机制深入: 虚函数在C++中的实现机制就是用虚表和虚指针。也就是每个类用了一个虚表,每个类的对象用了一个虚指针。具体的用法如下:
因为A有virtual void f()和g(),所以编译器为A类准备了一个虚表vtableA,内容如下:
B因为继承了A,所以编译器也为B准备了一个虚表vtableB,内容如下:
注意:因为B::g是重写了的,所以B的虚表的g放的是B::g的入口地址,但是f是从上面的A继承下来的,所以f的地址是A::f的入口地址。然后某处有语句 B bB;的时候,编译器分配空间时,除了A的int a,B的成员int b;以外,还分配了一个虚指针vptr,指向B的虚表vtableB,bB的布局如下:
关于虚函数下面的讲解下面博客总结的也很好:
参考维基百科补充些多态的知识: 多态是指计算机程序运行时,相同的消息可能会送给多个不同的类之对象,而系统可依据对象所属类,引发对应类的方法,而有不同的行为。简单来说,所谓多态意指相同的消息给予不同的对象会引发不同的动作称之。
最后来举个例子: 比如有动物(Animal)之类(Class),而且由动物继承出类鸡(Chicken)和类狗(Dog),并对同一源自类动物(父类)之一消息有不同的响应,如类动物有“叫()”之动作,而类鸡会“啼叫()”,类狗则会“吠叫()”,则称之为多态。
哈哈~~~~~~~~~~~~~~~~ 这下该对多态有个很好的认识了吧!!!!!!!!!!!!!! |
|
来自: 雪柳花明 > 《C 理论 面试准备》