面向对象:Objective-C 与 C++ 实现“多态”的原理

最近在学习 UE4(Unreal Engine)的相关知识,由于UE4引擎是使用C++实现的,因此对C++语言有了深一步的学习。我想,程序员在会某种语言的情况下,再学习其他语言时,总喜欢对比着学习,特别是同属于一类的,OC与C++同为编译型语言。C++也是一门使用C语言实现的面向对象语言。而OC的底层是C和C++。

OC与C++还是有很多不同的,比如OC的方法只声明不定义,编译可以通过,且可以只定义不声明,而C++声明和定义必须成对出现,且在其他地方调用的情况下,只声明不定义编译不通过。这是因为OC底层的有runtime框架。OC通过Interface实现抽象接口,C++是通过纯虚函数实现的抽象接口(virtual void function() = 0 这样就是一个纯虚函数,子类可以去写实现)。OC是无法多继承,但可以实现多接口;C++既可以实现多接口,也可以多继承。本文重点讨论OC与C++是如何实现“多态”的,以及有什么不同。

OC多态实现原理

OC是一门基于Runtime的动态语言,调用方法本质是调用了Runtime提供的发送消息API,其是通过字符串(也可以说是SEL)从方法列表里查找到方法,然后执行(调用IMP)。
其多态的实现是这样的,假如现有一个Animal类, 里面有一个 eat 方法并进行了实现,有一个从Animal继承而来的Cat类,也实现了eat方法。那么 Animal *cat = new Cat(); cat.eat(); 这里是执行了Cat类的eat实现。因为OC的方法是在一个方法数组里,在查找方法的过程中,先去查找子类的方法数组,找不到才去找父类的方法数组,所以子类的eat 是在父类的eat 之前找到的,由于找到了eat,就停止了查找,对,就是你想到的,OC的多态实现就是找到,停止,执行,不会往后找了。

C++多态实现原理

假如使用C++类来写上面的类和方法,Animal *cat = new Cat(); cat.eat(); 这里会执行 Animal的 eat,因为其函数指针是Animal。但是在声明方法的时候 添加 virtual 关键字,就可以实现多态,对,C++就是通过 虚函数(virtual) 来实现多态的。虚函数表是继承下来的,子类里重写了父类的虚函数,就会代替父类的虚函数的位置,如果是增加,就增加在虚函数表后面。

虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。

具体详看:C++虚函数表深入探索(详细全面)

猜你喜欢

转载自blog.csdn.net/Yj_sail/article/details/117417419