C++:类成员用作事件回调

Jar*_*arx 6 c++ oop events member-function-pointers event-handling

我正在尝试向我的项目添加一个简单的消息传递系统,其中事件可以由函数调用,这将导致注册到该事件的所有回调被调用.

现在,执行此操作的逻辑方法是使用函数指针.可以很容易地将指针传递给事件管理器所需的回调函数,以进行注册.事件回调函数总是返回一个intvoid*作为参数.

但是我不想将静态全局函数注册为我的事件回调 - 我想用类成员函数来做.

  • 是否有可能用C++实现这一目标?存储和调用指向不同类的成员函数但具有相同函数头的指针.

  • 如果这是不可能的,你对我如何解决这个问题有什么建议吗?我真的想直接向我的类添加事件监听器.

luk*_*uke 7

对的,这是可能的. C++ 0x具有function处理此问题的类,并且正如其他人指出的那样,Boost具有类似的功能.

你也可以自己动手,但语法不适合胆小的人:

#include <iostream>

class Callable
{
    public:

        virtual ~Callable() {}
        virtual int operator() (void* args) = 0;
};

class CallableFreeFunction  : public Callable
{
    public:

        CallableFreeFunction(int (*func)(void*)) : func_(func) {}

        virtual int operator() (void* args) { return (*func_)(args); }

    private:

        int (*func_)(void*);
};

template <typename tClass>
class ClassMemberCallable : public Callable
{
    public:

        ClassMemberCallable(tClass* instance, int (tClass::*memberfunction)(void*)) : instance_(instance), memberfunc_(memberfunction) {}

        virtual int operator() (void* args) { return (instance_->*memberfunc_)(args); }

    private:

        tClass* instance_;
        int (tClass::*memberfunc_)(void*);
};

class Foo
{
    public:

        int derp(void* args)
        {
            std::cout << args << '\n';
            return 2;
        }
};

int freefunctionfoo(void* args)
{
    std::cout << "free" << args << '\n';
    return 2;
}

int main(int argc, char* argv[])
{
    Foo myfoo;

    Callable* callable = new ClassMemberCallable<Foo>(&myfoo, &Foo::derp);

    (*callable)(0);

    delete callable;

    callable = new CallableFreeFunction(freefunctionfoo);

    (*callable)(0);

    delete callable;

    std::cin.get();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这演示了一种以不透明的方式处理自由函数和成员函数的方法.这是一个简单的例子,可以通过多种方式使其更通用和更健壮.我会向您推荐这些页面以获取语法帮助:

http://www.newty.de/fpt/index.html

http://www.parashift.com/c++-faq-lite/pointers-to-members.html

我还建议您查看更多想法:

http://www.codeproject.com/KB/cpp/FastDelegate.aspx


J.N*_*.N. 0

不,这是不可能的(除非您使用 .net 执行 c++/cli)。

现在,您仍然可以创建静态函数,将一个对象作为参数传递给它们,它们唯一要做的就是调用该对象上的成员函数。(实际上首先需要演员阵容)。