C++ C+的最佳实践+;函数指针/回调
在处理自定义回调或函数指针时,我正在寻找一些最佳实践方面的指导 我现在有两个主要的用例C++ C+的最佳实践+;函数指针/回调,c++,C++,在处理自定义回调或函数指针时,我正在寻找一些最佳实践方面的指导 我现在有两个主要的用例 我的类中有一个永远循环的阻塞循环。我希望外部用户能够指定在该循环的每次迭代中调用的函数 前 其中doStuff是一个位于别处的函数,它将在循环的每次迭代中被调用 我从一个可以对应多个值的函数中返回一个int。我想动态地将函数映射到这些值,这样我就可以对返回的int进行查找,然后调用相应的函数 前 其中int作为键来查找要调用的正确函数 我知道我这里的语法可能不正确,我需要使用std::map并传递指针等,但任
class Window {
public:
//The processing function can be from any class and takes in no arguments and returns void
template<class T>
std::function<void(T*, void)> processingFunction;
};
我觉得我完全缺少模板、std::function和/或std::bind。我又花了四个小时浏览互联网,也许我只需要睡一觉 我建议您使用
std::function
而不是指针。请注意,这是对标准库的TR1添加,您可以使用它的Boost实现来处理旧的实现。它的好处是,它接受任何类型的函数,这些函数不带参数,并返回与void
兼容的内容(即:返回任何内容)。您可以将它与std::bind
结合使用,以获得更大的灵活性
也就是说,您仍然需要一个
std::map
(或者如果索引是连续的,则需要一个普通的std::vector
)来从索引映射到函数。我建议您将回调定义为包含一个void*
参数,调用者在安装回调时指定该参数。这允许调用方将任意数据传递到其回调中,而回调通常是为该函数提供上下文所必需的。不需要此参数的调用方可以使用NULL来提供它
control.Invoke()
和control.BeginInvoke
在.NET的WinForms中执行此操作)。这可能会导致死锁,所以要小心myClass.setLoopFunction(NULL)
),不要忘记注销它,并在从循环调用它之前检查它是否已设置。这是可选的,我这样做只是为了提供更平滑的清理。如果循环需要高性能,可以跳过此步骤这真是太好了。。。在C++中有很多更好的方法!使用
void*
几乎总是一个糟糕的主意。酷,今晚我会试试。我是否应该担心性能方面的问题?对于无限while循环中的回调,比映射更重要。@Jon:是的,至少在Boost函数实现中,每个调用相当于两个常规函数调用或类似的调用。这一切都在他们避免虚拟调度的理由中得到了解释。这似乎比我想象的要困难。由于格式原因删除了注释,并编辑了我的原始问题。虽然这不是我需要的解决方案,但这并不是因为这个答案是错误的,而是因为我不了解如何正确使用std::function和bind。这仍然是一个复选标记,因为它引导我找到了使用上面的回调库的解决方案。所以我发现:它基本上完成了我需要它做的所有事情,而且似乎是一个性能良好的速率。为什么要重新发明方向盘?我仍然想进一步探索这段代码以真正理解它,但现在它解决了我的问题。谢谢大家的帮助/指导。
myFunctionMap[passedInt]();
class Window {
public:
//The processing function can be from any class and takes in no arguments and returns void
template<class T>
std::function<void(T*, void)> processingFunction;
};
while(true) {
if (exitCondition == false) {
//Execute processing function
processingFunction();
}
else {
break;
}
}