c++回调——编译时虚拟函数的替代品
c++ callbacks - compile time alternatives to virtual functions
我想要一个能够执行回调的通用可重用类。我通常使用虚函数来完成:
泛型类: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();
}
这似乎是一个可怕的大量的样板文件,只是为了连接回调。另一种选择是使用函子,这可能更简洁一些。
但是在我看来,很多东西在编译时就已经知道了。这是否可以简化,以便在编译时解析回调?
您可以使用奇怪的循环模板模式(CRTP)来实现静态多态性。
您可能会发现只需简单地使用std::函数就可以达到目的。这样,客户端就可以按照他们认为合适的方式实现他们的类,而不是被迫使用继承。
这也比C风格的回调更可取,C风格的回调通常需要一个void*
"用户数据"指针,以便能够正确地与想要使用成员函数的类一起工作。
您可以使用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();
我认为基于策略的设计是你正在寻找的:
http://en.wikipedia.org/wiki/Policy-based_design基本模式在Alexandrescu的"Modern c++ Design"中概述,并在其配套库"Loki"中使用。鉴于此,Loki库本身是如何使用策略设计的一个很好的参考。该库在sourceforge上:
http://loki-lib.sourceforge.net/index.php?n=Main.HomePage相关文章:
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 当覆盖存在时调用基本虚拟"binded to object"函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 类型擦除的std::function与虚拟函数调用的开销
- 重写虚拟函数和继承
- 是否可以使用函数指针调用虚拟析构函数?
- 在没有动态内存的世界中,我是否需要虚拟析构函数?
- 虚拟继承基构造函数消除
- "虚拟""覆盖"析构函数
- 类中的虚拟布尔函数参数不起作用
- 用纯虚拟函数兜圈子
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- 尝试在 QLabel 上绘画失败(无法在没有对象的情况下调用成员函数"虚拟无效 QLabel::p aintEvent(QPaintEvent*)")
- 声明析构函数虚拟就足够了吗?
- 视觉 C++当我们在基类中使函数成为纯虚拟时,那么在子类中再次使相同的函数虚拟的必要性是什么
- 重载函数(虚拟/非虚拟)