C++ 类成员回调
C++ Class member callback
我在编译此代码时出错:
template <class T> class purple_multitimer {
public:
typedef struct _timerinfo timerinfo, *ptimerinfo;
typedef gboolean (T::*multitimer_callback) (ptimerinfo pti);
typedef struct _timerinfo {
guint id;
multitimer_callback cb;
T * pthis;
purple_multitimer<T> * pmt;
} timerinfo, *ptimerinfo;
purple_multitimer() {
memset(m_ti, 0, sizeof(m_ti));
}
~purple_multitimer() {
stop();
}
void start(multitimer_callback mt_cb, T * pthis, guint timeout = 10) {
ptimerinfo pti = ti_get();
assert(pti);
pti->pthis = pthis;
pti->pmt = this;
pti->cb = mt_cb;
pti->id = purple_timeout_add_seconds(timeout, GSourceFunc(timeout_cb), pti);
}
void stop(multitimer_callback mt_cb = NULL) {
for (register guint n = 0; n < sizeof(m_ti)/sizeof(timerinfo); ++ n)
if (m_ti[n].cb == mt_cb) {
purple_timeout_remove(m_ti[n].id);
ti_zero(n);
}
}
private:
timerinfo m_ti[32];
inline ptimerinfo ti_get(guint n) {
return &m_ti[n];
}
inline ptimerinfo ti_get() {
for (register guint n = 0; n < sizeof(m_ti)/sizeof(timerinfo); ++ n)
if (m_ti[n].id == 0) return &m_ti[n];
return NULL;
}
inline ptimerinfo ti_zero(ptimerinfo pti) {
memset(pti, 0, sizeof(timerinfo));
return pti;
}
inline ptimerinfo ti_zero(guint n) {
memset(&m_ti[n], 0, sizeof(timerinfo));
return &m_ti[n];
}
static gboolean timeout_cb(ptimerinfo pti) {
gboolean res = (pti->pthis->*(pti->cb))(pti);
if (!res) pti->pmt->stop(pti->cb);
return res;
}
};
class _ctrl {
public:
purple_multitimer<_ctrl> pmt;
gboolean on_tomeout (purple_multitimer<_ctrl>::ptimerinfo pti) {
return false;
};
void on_connected(PurpleConnection *gc) {
pmt.start(purple_multitimer<_ctrl>::multitimer_callback(&_ctrl::on_tomeout), this);
}
void on_disconnected(PurpleConnection *gc) {
}
} controller;
编译此代码时出现错误:
[Error] E:dnc-imexchangednc-imexchange.cpp:117: error: no matching function for call to `purple_multitimer<_ctrl>::start(gboolean (_ctrl::*)(_timerinfo*), _ctrl* const)'
[Warning] E:dnc-imexchangednc-imexchange.cpp:52: note: candidates are: void purple_multitimer<T>::start(gboolean (T::*)(_timerinfo*), T*, guint) [with T = _ctrl]
我需要以这种方式实现回调。
如果你想要一些高质量的回调(能够一次调用多个函数,适合观察者模式),我可以建议 boost::signals2.
如果你只想调用一个函数作为回调,你可以使用 std::function:
void Foo(const std::function<bool (const int)> &callback)
{
const int number = 4;
if (callback(number))
{
std::cout << "Callback returned true!" << std::endl;
}
else
{
std::cout << "Callback returned false!" << std::endl;
}
}
// Use this if you have C++11
void CallFooLambda()
{
const auto lambda = [](const int number) -> bool
{
return number % 2;
};
Foo(lambda);
}
// Else use these functions
bool FooCallback(const int number)
{
return number % 2;
}
void CallFoo()
{
Foo(&FooCallback);
}
_ctrl是一个常量指针,您尝试调用的函数需要非常量 ptr-to _ctrl (pthis)。
你能定义pthis
如下吗?
T *pthis const
这应该使您的代码与错误消息中的"候选"匹配。
this
是无法更改的指针。
Boost.Function 是一个很好的工具包,用于简化回调语法和实现。
Boost.Function 库包含一个 类模板系列,它们是 函数对象包装器。这个概念 类似于通用回调。 它与功能共享功能 指针都定义了调用 接口(例如,一个函数需要两个 整数参数并返回 浮点值),通过该值 可以调用一些实现,并且 调用的实现可以 在整个过程中的变化 程序。
一般来说,任何地方 函数指针将用于 推迟呼叫或回拨, Boost.Function 可以用于 允许用户在 目标的实施。 目标可以是任何"兼容的" 函数对象(或函数指针), 意思是 由 Boost.Function 指定的接口 可以转换为参数 目标函数对象。
相关文章:
- 如何在C++中使用非静态成员函数作为回调函数
- 如何使用C++对象的成员函数作为 C 样式回调?
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 处理类内的回调时,必须调用对非静态成员函数的引用
- 如何将派生类中的成员函数作为回调传递?
- 将成员函数传递给glfwSet*回调
- 正在尝试为成员进行回调
- ROS 订阅回调 - 使用 boost::绑定成员函数
- 为什么可以在没有实例变量的情况下访问静态回调方法中的静态成员变量?
- 模板函数,用于在模板化对象上执行成员回调,而无需提供其实例
- 可以使用仅功能成员属性进行回调界面
- CPP成员对C回调包装器的反馈
- 将非静态成员函数作为回调传递
- 如何使用C lambda将成员功能指针转换为普通功能指针,以用作回调
- 如何在 Windows 上将成员函数作为与蓝牙相关的参数回调函数传递
- 用STD ::函数作为集体成员创建回调
- 访问作为WiFi侦听器回调成员函数一部分的类的成员
- C++来自不同类的多个回调成员函数,而无需 std 和 boost
- 指向SDL音频回调成员函数的指针
- 使用libevent回调成员函数