四、 多态的实现
在C++中多态有两种,编译时多态,与运行时多态。
而编译时多态指的是函数重载与运算符重载。编译时多态是主要是根据类型识别来实现的,是C++编译器在编译过程中完成的。既然C语言编译器原生就没有编译时多态的功能,那么要在C语言实现重载就必须借助于运行时的类型信息。
C语言在结构中插入运行信息的方法要么是:1.在结构体定义一个类型变量,保存对象的类型信息
2.在结构体定义一个指针,指向一个"类类型"的结构体
不管是前者还是后者,俺觉得都属于“C语言偏僻技巧”,所以放弃了重载的实现。
再说运行时多态,C++中的运行时多态指的就是虚函数。C++编译器实现虚函数就是在对象前头插入了个vtable,虚函数表。而我们先前在接口相关的定义中已经定义了函数表,下面俺就利用这个函数表来实现虚函数。
定义接口Iface:
定义个基类:
定义两个类ClassA和ClassB
重载Iface的两个函数init和dosomething,
实际上就是为struct Iface的两个结构体 i_face_for_ClassA, i_face_for_ClassB
填入不同的参数~~
为ClassA创建一个接口实例:
为ClassB创建一个接口实例:
分别实例化ClassA与ClassB:
试试多态 :)
小结:
虽然不愿意使用继承的关系,但是虚函数总是伴随着继承关系出现的。在实际运用多态性时,很可能需要在虚函数中进行类型的转换。这里就不作讨论了。。。
五、总结 :
不要说没可能在C语言里用面向对象的编程手法。不管是俺因为嵌入式、运行环境的限制,还是自己要写个动态语言。
很著名的一个例子就是PYTHON,PYTHON的原始版本就是用C实现的。在PYTHON解释器的源代码中,
每个数据类型都是一个对象,每个对象由一个结构体表示。而这个结构体里边用了宏的封装办法,也用了指向父类的指针。
虽然人家用了“C语言的偏僻技巧”,可人家是牛人呀,咱不能跟人比。。。
参考:
1.博客文章:《我所偏爱的 C 语言面向对象编程范式》 云风的BLOG
2.程序代码:《LW_OOPC》 http://sourceforge.net/projects/lwoopc/
3.图书:《Object-oriented Programming with ANSI-C》
4.图书:《Python源码剖析》