【问题标题】:Take member functions as parameters from multiple classes将成员函数作为多个类的参数
【发布时间】:2013-07-23 14:40:14
【问题描述】:

我正在研究一个输入系统。在该系统中,对象可以注册一个函数,以便在按下某个键时调用。然而,注册的方法是该对象的成员,所以我的注册函数必须看起来像这样:

void register(EventType type, Class* object, void (Class::*function)()){ //保存这个 }

问题是注册函数的类并不总是相同的,所以这行不通。反正有这个吗?

【问题讨论】:

  • 模板。使用模板化的子类创建一个基本回调类。

标签: c++ oop member-function-pointers


【解决方案1】:

您可以将std::function<void()>存储在您注册回调的类中,然后添加一个函数模板register成员函数:

struct Foo
{
  template <typename F>
  void register(EventType type, F&& fun)
  {
    // make an std::function<void()> from fun and store
  }
};

然后,在调用方绑定Class 实例和Class 成员函数。

struct Bar { void bar() {} };
void foobar() { std::cout << "foobar!\n"; }

Foo f;
Bar b;
f.register(event1, std::bind(&Bar::bar, b)); // will call b.bar()
f.register(event2, foobar);                  // will call foobar()

【讨论】:

  • 调用这个函数会是什么样子?我认为 F&& 是一个函数指针。
  • @handuel F&amp;&amp; 是一种模板技术,它使用引用折叠来很好地处理左值或右值引用。你不必为此担心太多。我添加了一个小例子。我还在a blog 上写过类似的东西。
  • @handuel 请注意,这需要 C++11,但如果您没有编译器支持,那么您可以对 boost 执行几乎相同的操作(&amp;&amp; 除外) .
  • 你知道这是否适用于 g++ 吗?当我调用编译器时,我是否必须使用命令行参数告诉它使用哪个标准?
  • @handuel 这取决于版本。我不确定所有功能需要什么版本才能工作,但我觉得 4.6 应该足够了。
【解决方案2】:

这是一种不需要模板和函数指针的方法。你有一个像这样的观察者(回调)类:

class MyCallback {
    public:
    virtual void run(int abc)
    {
        cout << "MyCallback::run(" << abc << ")" << endl;
    }
};

然后你用父类 MyCallback 实例化你的观察者类:

class Test : public MyCallback
{
    public:
    void run(int abc)
    {
        MyCallback::run(abc);
    }
};

调用所有观察者的类:

class Subject
{

    vector<MyCallback*> observers;

    public:

    void reg_observer(MyCallback* cb)
    {
        observers.push_back(cb);
    }

    void call_out(int abc)
    {
        vector<MyCallback*>::iterator it;
        for(it=observers.begin();it!=observers.end();it++)
        {
            (*it)->run(abc);
        }

    }

};

测试代码:

void testcb()
{
    Test ttt;
    Subject s;

    s.reg_observer(&ttt);
    s.call_out(123);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    • 2021-09-04
    • 1970-01-01
    • 2023-04-02
    • 2015-01-15
    • 1970-01-01
    相关资源
    最近更新 更多