函数指针的进化论(1)
函数指针 (function pointer) 是传统 C 语言中少数的动态机制,但是近来许多语言都不再支持函数指针 (包括 Java 和 C#),而改用其它机制来代替。本文章简单扼要地说明,多态 (polymorphism)、反射 (reflection)、委托 (delegate) 如何取代函数指针。
http://www.microsoft.com/taiwan/msdn/columns/donet/functionpointer_1.htm
http://www.microsoft.com/taiwan/msdn/columns/donet/functionpointer_2.htm
摘要
函数指针 (function pointer) 是传统 C 语言中少数的动态机制,但是近来许多语言都不再支持函数指针 (包括 Java 和 C#),而改用其它机制来代替。本文章简单扼要地说明,多态 (polymorphism)、反射 (reflection)、委托 (delegate) 如何取代函数指针。
函数指针(function pointer) 是一种「指向函数的指针」,和一般指向资料的指针不同。凡是研究过许多系统原代码 (例如:Linux Kernel、Borland OWL) 的人,对于函数指针应该都不陌生,因为多数低阶系统都使用 C 语言编写,而函数指针是传统C语言中少数的动态机制,有许多不可取代的地方,所以这些 C 原代码中到处可见函数指针。
透过一个实际的范例,来了解何谓函数指针:
// FncPtr.cpp#include using std::cin;using std::cout;using std::endl;// 声明 Fnc1(), Fun2(), Twice()
float Fnc1(int);float Fnc2(int);double Twice(float (*)(int), int);// 主程序
int main() { int A = 3; int B = 5;count << "Twice(Fnc1, A)的值为: "
<< Twice(Fnc1, A) << endl;count << "Twice(Fnc2, B)的值为: "
<< Twice(Fnc2, B) << endl;}float Fnc1(int N) { return float (N*N);}float Fnc2(int N) { return float (N*N*N);}double Twice(float (*pF)(int), int N) { return 2.0 * double(pF(N));}
执行结果:
Twice(Fnc1, A)的值为:18
Twice(Fnc2, B)的值为:250
此例中,pF 即为函数指针,而函数名称本身 (Fun1 与 Fun2) 是常数的函数指针。通过函数指针,函数被资料化了 (变成指针),如此一来函数也可以被传递、被纪录,所以 Fnc1 与 Fnc2 可以被当成参数,传进 Twice() 中。
一旦函数可以被传递、被纪录,这开启了许多可能性,产生许多有趣的应用,特别是下列三者:
· 多态 (polymorphism):稍后再说明。
· 多线程 (multithreading):将函数指针传进负责建立多线程的 API 中:例如 Win32 的 CreateThread(...pF...)。
· 回调 (call-back):所谓的回调机制就是:「当发生某事件时,自动呼叫某段程序代码」,Charles Petzold 称此为「Don’t Call Me, I'll Call You」。事件驱动 (event-driven) 的系统经常透过函数指针来实现回调机制,例如 Win32 的 WinProc 其实就是一种回调,用来处理窗口的讯息。
函数指针的致命缺点是:无法对参数 (parameter) 和返回值 (return value) 的型态进行检查,因为函数已经退化成指针,指针是不带有这些型态信息的。少了型态检查,当参数或返回值不一致时,会造成严重的错误。编译器和虚拟机器 (VM) 并不会帮我们找出函数指针这样的致命错误。所以,许多新的程序语言不支持函数指针,而改用其它方式。
多态
多态的实现方式很复杂,大致上是编译器或 VM 在数据结构内加入一个资料指针,此指针通常称为 vptr,是 Virtual Table Pointer 的意思。vptr 指向一个 Virtual Table,此 Virtual Table 是一个数组 (array),由许多函数指针所组成,每个函数指针各自指向一个函数的地址。如图 1 所示。
(未完待续)
作者:蔡學鏞 更新日期:2004-11-07
来源:MSDN台湾
浏览次数:
相关文章
相关评论 发表评论
- No Comments
