将方法作为从一个类回调到另一个类的方法

时间:2013-11-17 23:09:53

标签: c++ class methods callback

我有2个课程,我想通过回调将方法从一个方法传递给另一个方法!

看到我也希望使用void(* callBack)();

来保存此方法的地址

我习惯在C中这样做,但我不知道如何在c ++中这样做;

#include <iostream>

using namespace std;

class A
{
    private:
        void (*callBack)(); //to hold the address of the method

    public:
        A();
        void setCallBack(void(*cB)());
        void useCallBack();
};


A::A()
{

}

void A::setCallBack(void(*cB)())
{
    callBack = cB;
}

void A::useCallBack()
{
    callBack();
}


class B
{
    private:
        A * Aguy;

    public:
        B();
        void someMethod();
        void otherMethod();
};

B::B()
{
    Aguy = new A();
}

void B::otherMethod()
{
    Aguy->setCallBack(someMethod);
    Aguy->useCallBack()
}

void B::someMethod()
{
    cout << "Hello. I'm from class b" << endl;
}

int main()
{
    B Bguy;
    Bguy.otherMethod();

    return 0;
}

3 个答案:

答案 0 :(得分:3)

问题在于:

    void (*callBack)();

这不是指向方法的指针。这是一个指向函数的指针 要获得指向方法的指针,您需要指定方法所在的类。

    void (B::*callBack)();

然后当你调用它时,你需要通过一个对象来调用它。

 void A::useCallBack(B* b)
 {
      (b->*callBack)();
 }

但这可能不是你想要的。
你真正想要的是一个封装所有这些的包装器。

我会看看std :: function。这将允许您将方法调用和对象包装到您可以调用的单个对象中。

std::function<void()>   callback;

只需将所有出现的void(*cB)()替换为std::function<void()>,然后就可以将对象的实例绑定到调用点的方法。

Aguy->setCallBack(std::bind(&B::someMethod, this));

这也允许您将任何正常函数或函子作为回调传递。

void print()
{    std:cout << "It worked\n";
}
...
Aguy->setCallBack(&print);

struct Printer
{
     void operator()() const
     {
         std::cout << "It worked with  obejct\n";
     }
}
...
Aguy->setCallBack(Printer());

答案 1 :(得分:1)

有关详细信息,请参阅c++ - <unresolved overloaded function type>

引用答案:

  

在C ++中,成员函数有一个指向的隐式参数   对象(成员函数内的this指针)。正常C.   函数可以被认为具有不同的调用约定   从成员函数,所以他们的指针类型   (指向成员函数的指针与指向函数的指针)是不同的   不相容。 C ++引入了一种新类型的指针,称为a   指向成员的指针,只能通过提供对象来调用。

将静态放在someMethod

class B
{
    private:
        A * Aguy;

    public:
        B();
        static void someMethod();
        void otherMethod();
};

void B::otherMethod() {
    Aguy->setCallBack(B::someMethod);
    Aguy->useCallBack(); // adding missing semicolon
}

答案 2 :(得分:0)

如果需要传递成员函数指针,请参阅修改后的代码。它使用现代的c ++构造。

#include <iostream>
#include <functional>
using namespace std;


class A
{
private:
    typedef std::function<void(void)> some_void_function_type;
    some_void_function_type f_;
public:
    A();
    void setCallBack(some_void_function_type f);
    void useCallBack();
};


A::A()
{

}

void A::setCallBack(some_void_function_type f)
{
    f_ = f;
}

void A::useCallBack()
{
    f_();
}


class B
{
private:
    A * Aguy;

public:
    B();
    void someMethod();
    void otherMethod();
};

B::B()
{
    Aguy = new A();
}

void B::otherMethod()
{
    Aguy->setCallBack(std::bind(&B::someMethod, this));
    Aguy->useCallBack();
}

void B::someMethod()
{
    cout << "Hello. I'm from class b" << endl;
}

int main()
{
    B Bguy;
    Bguy.otherMethod();

    return 0;
}