指向不同 类 成员函数的指针

Pointer to member functions of different classes

在 class A 中,我有一个成员函数应该从其他 classes 接收指向函数的指针。所有这些函数都具有相同的签名(接收类型和 return 类型)。

像这样:

class A{
private:
    void (*onConfirmCallback) (); //pointer to function
public:
    void setOnConfirmListener(void (*callback) ()); //member function that receives another member function from another class, and uses the pointer above to point to it
}

定义:

void A::setOnConfirmListener(void (*callback)())
{
    onConfirmCallback = callback;
}

并且在 class A 的某个时候我调用回调:

onConfirmCallback();

在classB我设置回调:

class B{
private:
    A a;
public:
    B();
    foo();
}

和定义:

B::B(){
    a.setOnConfirmListener(foo);
}
B::foo(){
    cout << "foo called" << endl;
}

我还有另一个 class C,它也有一个 A 的实例,并且还设置了一个回调:

class C{
private:
    A a;
public:
    C();
    foo2();
}

和定义:

C::C(){
    a.setOnConfirmListener(foo2);
}
C::foo2(){
    cout << "foo2 called" << endl;
}

我尝试了不同的声明变体,上面的代码产生了这个错误:

no matching function for call to 'A::setOnConfirmListener()'

我了解 "pointers to functions" 与 "pointers to member functions" 不同。所以我也尝试将 void (*onConfirmCallback) () 更改为 void (B::*onConfirmCallback) () ,但我认为这不是很好,因为这个指针应该包含对不同 classes 的回调(它们不是从相同的基础 class) 而不仅仅是 B.

有没有办法实现这个?

基本上我正在尝试做一些类似于Java的界面...

使用 std::function 而不是函数指针。

class A {
private:
    std::function <void()> onConfirmCallback; //pointer to function
public:
    void setOnConfirmListener(std::function <void()>);
};

您可以将非成员函数直接传递给setOnConfirmListener。说到成员函数,你需要一个对象才能调用它们:

class B {
private:
    A a;
public:
    B();
    void foo();
};

B::foo(); // invalid and makes no sense
B* b = new B; b->foo(); // OK

因此下面的行也不起作用:

a.setOnConfirmListener(&B::foo); // invalid and makes no sense

您可以使用 std::bind:

传递对象及其成员函数
a.setOnConfirmListener(std::bind(&B::foo, b)); // OK

b 可以是 B&B*std::shared_ptr<B>.

使用 this(或 *this)作为 bind 的第二个参数可能有点危险,因为您现在负责监视您的对象何时不复存在并且注销所有关联的侦听器。解决此问题的一种方法是从 enable_shared_from_this 派生对象并使用 std::shared_ptr 而不是原始 this 指针。这意味着您的对象只有在至少一次回调中注册为侦听器后才会被销毁。

另一种方法是从相同的抽象基础 class 派生所有侦听器,例如 Listener,并使用 指向 Listener 的指针而不是函数指针。

class Listener
{
  public:
    virtual void callback() = 0; 
};

class A {
private:
    std::shared_ptr<Listener> listener; // or another smart pointer
public:
    void setOnConfirmListener(std::shared_ptr<Listener> listener);
};

class B : public Listener {
private:
    A a;
public:
    B();
    void foo();
    void callback() { foo(); }
};

缺点是必须从同一个基础派生所有听众 class。另外,如果同一个 class 需要有多个监听器回调,你就得跳过一些圈套了。