繁体   English   中英

C ++函数指针/回调的最佳实践

[英]Best Practice for C++ Function Pointers/Callbacks

在处理自定义回调或函数指针时,我正在寻找最佳实践方面的一些指导。

我现在有两个主要用例。

  1. 我的班级里面有一个阻塞循环,永远循环。 我希望外部用户能够指定在该循环的每次迭代中调用的函数。

防爆。

myClass.setLoopFunction(doStuff); 

doStuff是位于其他地方的函数,它将在循环的每次迭代中被调用。

  1. 我从一个可以对应多个值的函数中获取一个int。 我想动态地将函数映射到这些值,所以我可以在int上查找,然后调用相应的函数。

防爆。

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的东西。 然后,这是一个很好的四个小时的互联网搜索,所以也许我只需要睡在它上面。

我建议你使用std::function< void() >而不是指针。 请注意,这是标准库的TR1添加,您可以使用它的Boost实现来处理旧的实现。 它的好处是它采用任何类型的函数不带参数并返回与void兼容的东西(即:返回任何东西)。 您可以将它与std::bind以获得更大的灵活性。

也就是说,你仍然需要一个std::map< int, std::function< void() > > (或者如果你的索引是顺序的普通的std::vector )来从索引映射到函数。

我建议您定义回调以包含void *参数,调用者在安装回调时指定该参数。 这允许调用者将任意数据传递到它们的回调中,这通常需要为该函数提供上下文。 不需要此参数的调用者可以使用NULL来提供它。

  1. 如果你的回调最终回调到GUI访问代码,你可能需要将控制权分派给GUI线程( Control.Invoke()Control.BeginInvoke在.NET的WinForms中执行此操作)。 这可能会导致死锁,所以要小心。
  2. 作为前一点的概括,请记住在回调调用期间,循环函数将无法处理请求。 所以在回调函数中,尽可能少地工作,或者如果你需要做cpu密集的东西,则产生另一个线程。 并尽量避免调用阻塞函数。
  3. 不再忘记在不再需要时取消注册回调( myClass.setLoopFunction(NULL) ),并在从循环中调用它之前检查它是否已设置。 这是可选的,我只是为了提供更顺畅的清理。 如果循环需要高性能,则可以跳过此步骤。
  4. 什么@ K-ballo说。 关于@ mah的建议,可以使用界面或模板来完成

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM