我希望一个通用的可重用类能够执行回调。我通常使用虚函数来执行此操作:
通用类:
class LibraryClass
{
private:
virtual void SomeCallback(){}
};
使用泛型类的代码:
class AppClass;
class LibraryClassWrapper: public LibraryClass
{
public:
LibraryClassWrapper(AppClass& appClass):appClass_(appClass){}
private:
virtual void SomeCallback();
AppClass& appClass_;
};
class AppClass
{
public:
AppClass():libraryClassWrapper_(*this){}
void handleCallbackFromLibraryClass()
{
std::cout << "Handling callback" << std::endl;
}
private:
LibraryClassWrapper libraryClassWrapper_;
};
void LibraryClassWrapper::SomeCallback()
{
appClass_.handleCallbackFromLibraryClass();
}
这似乎是一个非常多的样板,只是为了连接一个回调。另一种方法是使用仿函数,它可能更清洁一些。
但是我发现在编译时已经知道了很多。这可以简化,以便在编译时解决回调吗?
答案 0 :(得分:5)
您可以使用 Curiously recurring template pattern(CRTP) 来实现静态多态性。
答案 1 :(得分:3)
你可能会发现只是简单地使用std :: function就可以了。这样客户端可以实现他们的类,但他们认为合适而不是被迫使用继承。
这也优于C风格的回调,通常需要void*
&#34;用户数据&#34;指针,以便能够与想要使用成员函数的类一起正常运行。
您可以使用lambda捕获您需要的任何状态,并且可以让回调的接口仅反映与通知相关的内容。应该像这样简单:
#include <functional>
typedef std::function<void()> CallbackType;
struct Example
{
void CallbackHandler()
{
/* do something */
}
};
void FreeFunctionHandler()
{
/* do something */
}
// Use lambda to call member function of 'example'
Example example;
CallbackType callback1 = [&example]() { example.CallbackHandler(); };
// Use free function
CallbackType callback2 = FreeFunctionHandler;
// Execute callbacks
callback1();
callback2();
答案 2 :(得分:1)
我认为基于政策的设计是您正在寻找的:
http://en.wikipedia.org/wiki/Policy-based_design
Alexandrescu的“现代C ++设计”概述了基本模式,并用于伴随库“Loki”。鉴于此,Loki图书馆本身就是如何通过政策使用设计的一个很好的参考。该库位于sourceforge: