前两篇文章主要讲述了 C 语言面向对象编程– 封装和继承。本篇文章继续来讨论一下,如何使用 C 语言实现面向对象编程的另一个重要特性:多态。
对于多态的概念,网上已经有很多描述,简而言之,就是同一个接口的多种状态
通俗一点解释,多态就像是X-Man(X 战警)里面的魔形女角色,可以根据不同的战斗场景,改变自身的特征状态,同一个魔形女,不同的角色状态。
在 C++ 语言中,多态是存在于基类和派生类的关系里面的,实现运行时多态需要使用虚函数或抽象类。
C++ 多态
C++语言所描述的多态,分为编译时多态(也可以理解为重载)和运行时多态。
编译时多态并没有使用虚函数,这是因为程序在编译阶段已经确定了其执行关系,所以,一般可以把这种多态理解为函数的重载。
而运行时多态,则需要使用虚函数,使用虚函数是为了在程序编译的时候告诉编译器,这个函数需要在执行的时候才能确定其执行关系。
以下通过两段代码,简单描述一下 C++ 语言如何使用虚函数实现运行时多态。
头文件 polymorphism_test.h
源文件 polymorphism_test.cpp
从上面的代码可以看出,在头文件polymorphism_test.h 里面,声明了一个基类Coordinate和一个派生类Rectangle,基类和派生类里面都有各自的属性和虚函数。
基类的虚函数和父类的虚函数一致。在源文件polymorphism_test.cpp里面,分别实现了基类和派生类的构造函数和虚函数。
编写一个测试函数,用来测试以上的代码,测试函数内容如下所示:
代码运行结构,如下所示:
从以上的测试代码可以看出,基类指针指向基类对象的时候,就可以调用基类的函数方法。当基类指针指向派生类对象时,就可以调用派生类的函数方法。
在代码里面,运行时都是同样调用 p_base->display_params() 这段代码,但却可以有不同的表现形式,这种现象就是多态。
在创建基类对象和父类对象的时候,由于虚函数的存在,编译器会为每个对象创建一个虚函数表,这个虚函数表就是基类指针能找到要具体实现的函数的关键所在。
由于虚函数表的存在,因此我们可以通过基类指针对所有派生类的虚函数进行访问,以上就是C++语言中,封装、继承和多态的简单实现。
在C语言中,也可以使用一些技巧(主要是使用函数指针)实现多态。以下是C语言实现多态的具体内容。
C 语言多态
使用 C 语言实现多态,除了使用结构体构建出一个父类,还需要先构建出一个虚函数表,这个虚函数表就是一系列函数指针的结构体。
简单来说,就是在结构体里面包含了函数指针作为函数的接口,而这个函数指针则可以根据程序运行时的情况,分别赋予不同的函数入口,从而实现同一个接口不同的功能调用。