sbi*_*sbi 106
大多数示例归结为回调:您调用一个函数f()传递另一个函数的地址g(),并f()调用g()某些特定任务.如果您传递f()了h()相反的地址,f()则会回拨h().
基本上,这是一种参数化函数的方法:其行为的某些部分不是硬编码的f(),而是进入回调函数.f()调用者可以通过传递不同的回调函数来使行为不同.经典qsort()来自C标准库,它将其排序标准作为指向比较函数的指针.
在C++中,这通常使用函数对象(也称为仿函数)来完成.这些是重载函数调用操作符的对象,因此您可以像调用函数一样调用它们.例:
class functor {
public:
void operator()(int i) {std::cout << "the answer is: " << i << '\n';}
};
functor f;
f(42);
Run Code Online (Sandbox Code Playgroud)
这背后的想法是,与函数指针不同,函数对象不仅可以携带算法,还可以携带数据:
class functor {
public:
functor(const std::string& prompt) : prompt_(prompt) {}
void operator()(int i) {std::cout << prompt_ << i << '\n';}
private:
std::string prompt_;
};
functor f("the answer is: ");
f(42);
Run Code Online (Sandbox Code Playgroud)
另一个优点是,与通过函数指针调用相比,有时更容易内联调用函数对象.这就是为什么在C++中排序有时比在C中排序更快的原因.
Maw*_*awg 39
好吧,我通常在跳转表中使用它们(专业)(另请参阅此StackOverflow问题).
跳转表通常(但不是唯一地)用于有限状态机中以使它们被数据驱动.而不是嵌套的开关/案例
switch (state)
case A:
switch (event):
case e1: ....
case e2: ....
case B:
switch (event):
case e3: ....
case e1: ....
Run Code Online (Sandbox Code Playgroud)
你可以制作一个2d数组或函数指针,然后调用 handleEvent[state][event]
Car*_*icz 10
函数指针有用性的"经典"示例是C库qsort()函数,它实现了快速排序.为了对用户可能提出的任何和所有数据结构进行通用,它需要几个指向可排序数据的void指针和一个指向知道如何比较这些数据结构的两个元素的函数的指针.这允许我们创建我们的工作选择功能,事实上甚至允许在运行时选择比较功能,例如用于升序或降序排序.
我要反对现在的情况.
在C中,函数指针是实现自定义的唯一方法,因为没有OO.
在C++中,您可以使用函数指针或函子(函数对象)获得相同的结果.
由于它们的对象性质,仿函数比原始函数指针具有许多优点,特别是:
operator()lambda和bind)建造我个人更喜欢函子指针(尽管有样板代码),主要是因为函数指针的语法很容易变得毛茸茸(来自函数指针教程):
typedef float(*pt2Func)(float, float);
// defines a symbol pt2Func, pointer to a (float, float) -> float function
typedef int (TMyClass::*pt2Member)(float, char, char);
// defines a symbol pt2Member, pointer to a (float, char, char) -> int function
// belonging to the class TMyClass
Run Code Online (Sandbox Code Playgroud)
我唯一一次见过函数指针,而函数指针在Boost.Spirit中没有.他们完全滥用语法将任意数量的参数作为单个模板参数传递.
typedef SpecialClass<float(float,float)> class_type;
Run Code Online (Sandbox Code Playgroud)
但由于可变参数模板和lambdas即将到来,我不确定我们将在纯C++代码中使用函数指针.
我最近使用函数指针来创建一个抽象层.
我有一个用纯C编写的程序,可以在嵌入式系统上运行.它支持多种硬件变体.根据我运行的硬件,它需要调用某些功能的不同版本.
在初始化时,程序会计算出运行的硬件并填充函数指针.程序中的所有高级例程都只调用指针引用的函数.我可以添加对新硬件变体的支持,而无需触及更高级别的例程.
我曾经使用switch/case语句来选择正确的函数版本,但随着程序越来越多以支持越来越多的硬件变体,这变得不切实际.我不得不在整个地方添加案例陈述.
我也尝试过中间函数层来确定使用哪个函数,但它们没有多大帮助.每当我们添加新变体时,我仍然需要在多个位置更新case语句.使用函数指针,我只需要更改初始化函数.
| 归档时间: |
|
| 查看次数: |
11538 次 |
| 最近记录: |