函数指针的面向对象包装器






3.89/5 (13投票s)
2004 年 9 月 9 日
2分钟阅读

71730

395
函数指针为一阶函数提供了一个方便的机制,但在使用上相当复杂。 本文给出了这些函数指针的包装器,使它们的使用更容易。
引言
有时函数仅在您无法使用变量表达的几个方面有所不同,您真正喜欢做的是传递一个可以处理“特殊”情况并保持抽象性的函数。 在某些语言(如Scheme)中,您可以将函数作为参数传递; 在C++中,您必须使用函数指针。
函数指针对于C来说是一个很好的系统,但不适用于C++;您必须定义一个非类成员或静态类成员……因此,如果不使用全局变量,我们将无法访问类的非静态数据成员。
解决方案是创建一个函数指针的包装器,其中包含函数指针和指向类的指针。
注意:STL使用的另一种替代方法是函数对象; 我不喜欢这种方法,因为它会导致太多的类型工作 ;)。
用法
我将描述一个关于如何合并/使用函数指针包装器的简短指南。
- 将以下语句添加到您的头文件
... #include "functor.h" ...
- (可选) 对模板化函数指针执行
typedef
,这使得它更容易阅读:)。建议在您的类定义中进行此
typedef
,以防止污染您的全局命名空间。 我通常将它们放在类的私有声明中。typedef Functor<Test, void, int> Function;
在此示例中,
Test
是包含该函数的类,void
是函数的返回值,int
是函数的唯一参数。 - 定义你的类,我在这里添加了一个快速的类示例
/* * header file */ class Test { public: void TestFunc(); private: void Add(int x); void Mul(int x); void DoSomething(int x, Function f); int value_; }; /* * source file */ void Test::Add(int x) { value_ += x; } void Test::Mul(int x) { value_ *= x; } void Test::DoSomething(int x, Function f) { // some very complicated code ... f(x); ... // lots of other code }
在示例中,您应该注意
f(x)
,这是函数指针包装器的调用。 看起来完全像一个常规函数调用,但是f
是函数的参数。 - 创建函数指针包装器
void Test::TestFunc() { // create the function pointer wrapper (functor) Function myadd(this, &Test::Add); Function mymul(this, &Test::Mul); // now do the action! DoSomething(5, myadd); }
您只需将两个参数传递给构造函数即可创建一个包装器对象:函数的主机类(通常是
this
)和包装器应使用的方法名称。现在您可以将该函数传递给任何方法,并像调用普通函数一样调用它:)
技术资料
包装器的系统基于模板和运算符重载的使用。 模板用于使其更通用(即,能够为具有指定数量参数的任何函数创建包装器)。 运算符重载用于模拟常规的过程调用,我们重载operator()
来实现此目的。
已知限制
源代码仅包含一个和两个参数的包装器。 如果您需要更多,则需要扩展类或传递包含数据的struct
/class
作为单个参数。
待办事项
- 与
const
成员函数的兼容性 - 创建一个示例项目
- 创建一个内联版本,与VC++ 6或更低版本兼容。
历史
- 1.0.1版 - 2004年9月12日
根据Roland Pibinger和KevinHall的建议进行了一些更正。 谢谢!
- 1.0.0版 - 2004年9月9日
初始发布。