在C++中回调类的最干净的方法是什么?
我通常创建如下函数:
void registerCallback(void(*callback)(void* param), void* param);然后这样叫它:
foo->registerCallback(callbackStatic, this);然后,我在类中添加一个静态函数,如下所示:
static void callbackStatic(void* param)
{
    ((Type*)(param))->callback();
}它是有效的,但它很痛苦。我必须为每个回调函数创建两个函数。如果我可以使用C++11,我会使用lambda。Qt有一个非常好的信号和槽机制,但需要一个特殊的预编译器。
我正在编写一个库,所以我想尽可能地降低要求。没有C++11,没有boost等等。有没有一种方法可以只使用C++03来构建一个lambda或signal/slot 'like‘回调系统?
发布于 2016-09-17 02:22:35
如果您能够从头开始,我建议不要在C++中使用函数作为回调函数。取而代之,使用对象。
struct CallbackHandler { virtual void doit() = 0; };
void registerCallback(Callbackhandler* handler);然后
struct MyCallbackHandler : public CallbackHandler { ... };
registerCallback(new MyCallbackHandler());发布于 2016-09-17 02:39:45
这可能有点复杂,但对我来说很有效:
#include <functional>
#include <iostream>
#include <vector>
class C {
public:
    void foo() {
        std::cout << "foo" << std::endl;
    }
};
class D {
public:
    void bar() {
        std::cout << "bar" << std::endl;
    }
};
class abstract_bind {
public:
    virtual void operator()() = 0;
    virtual ~abstract_bind() {}
};
template <typename F, typename T>
class bind : public abstract_bind {
public:
    bind(F f_, T *t_) : f(f_), t(t_) {}
    virtual void operator()() {
        f(t);
    }
private:
    F f;
    T *t;
};
int main() {
    C c1, c2;
    D d;
    std::vector<abstract_bind*> v;
    v.push_back(new bind<std::mem_fun_t<void, C>, C>(std::mem_fun(&C::foo), &c1));
    v.push_back(new bind<std::mem_fun_t<void, C>, C>(std::mem_fun(&C::foo), &c2));
    v.push_back(new bind<std::mem_fun_t<void, D>, D>(std::mem_fun(&D::bar), &d));
    for (size_t i=0; i<v.size(); ++i)
        (*v[i])();
    for (size_t i=0; i<v.size(); ++i)
        delete v[i];
    return 0;
}其基本思想是使用std::mem_fun获取对象的成员函数,并将相应的this指针绑定到该成员函数以获得“普通”函数。
发布于 2016-09-17 04:30:41
您可以保留C风格的回调,并使用一个结构来调用成员函数:
// C-style callback
// ================
void(*registered_callback)(void* param) = 0;
void* registered_param = 0;
void registerCallback(void(*callback)(void* param), void* param) {
    registered_callback = callback;
    registered_param = param;
}
void unregisterCallback(void(*callback)(void* param), void* param) {
    registered_callback = 0;
    registered_param = 0;
}
// Invoker
// =======
struct InvokerBase {
    static void callInvoker(void* invoker) {
        reinterpret_cast<InvokerBase*>(invoker)->apply();
    }
    virtual void apply() const = 0;
};
template <typename T>
class Invoker : public InvokerBase
{
    public:
    Invoker(T& object, void(T::*function)())
    : object(&object), function(function)
    {
        registerCallback(callInvoker, this);
    }
    ~Invoker() {
        unregisterCallback(callInvoker, this);
    }
    void apply() const {
        (object->*function)();
    }
    private:
    Invoker(const Invoker&); // no copy
    Invoker& operator = (const Invoker&); // no copy
    T* object;
    void (T::*function)();
};
// Test
// ====
#include<cassert>
#include<iostream>
struct Type {
    void print() { std::cout << "Hello\n"; }
};
int main()
{
    Type x;
    {
        Invoker<Type> print_invoker(x, &Type::print);
        registered_callback(registered_param);
    }
    assert(registered_callback == 0);
}https://stackoverflow.com/questions/39537686
复制相似问题