我有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;
}
答案 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;
}