在处理自定义回调或函数指针时,我正在寻找最佳实践方面的指导。
我现在有两个主要用例。
实施例。
myClass.setLoopFunction(doStuff);
doStuff是位于其他地方的函数,它将在循环的每次迭代中被调用。
实施例。
myFunctionMap[passedInt]();
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;
};
我想要的功能是任何类都可以传入一个接受0参数并返回void的函数,我会将其设置为我的处理函数。在while循环中,我将执行该processingFunction,它将调用该原始类的成员函数。
while(true) {
if (exitCondition == false) {
//Execute processing function
processingFunction();
}
else {
break;
}
}
我觉得我完全错过了模板,std :: function和/或std :: bind的东西。然后,这是一个很好的四个小时的互联网搜索,所以也许我只需要睡在它上面。
答案 0 :(得分:7)
我建议您使用std::function< void() >
而不是指针。请注意,这是标准库的TR1添加,您可以使用它的Boost实现来处理旧的实现。它的好处是它采用任何类型的函数不带参数并返回与void
兼容的东西(即:返回任何东西)。您可以将其与std::bind
结合使用,以获得更大的灵活性。
也就是说,如果您的索引是连续的,您仍然需要std::map< int, std::function< void() > >
(或普通的std::vector
来映射索引到函数。
答案 1 :(得分:1)
我建议您定义回调以包含void *
参数,调用者在安装回调时指定该参数。这允许调用者将任意数据传递到它们的回调中,这通常需要为该函数提供上下文。不需要此参数的调用者可以使用NULL来提供它。
答案 2 :(得分:0)
Control.Invoke()
和Control.BeginInvoke
在.NET的WinForms中执行此操作。这可能会导致死锁,所以请小心。myClass.setLoopFunction(NULL)
),并在从循环调用它之前检查它是否已设置。这是可选的,我只是为了提供更顺畅的清理。如果您的循环需要高性能,则可以跳过此步骤。