我们为客户提供了一个简单的通信库。
我的问题是:如何保存指向客户类的方法的指针?
Library.h
是包含客户建立通信所需的所有方法的头文件。
library.cpp
是我们的代码。我必须在这里的某个地方保存指向我们客户的回调函数方法的指针。
customer.cpp
是客户如何使用我们的库的示例。
library.h:
// This is the header file what our customer gets
class Library {
public:
template <class Object, class Function>
void SetCallback(Object &obj, Function f);
};
library.cpp:
struct T_CUSTOMER {
Object o; // <- ???
Function f; // <- ???
} customer;
void Library::SetCallback(Object &obj, Function f) {
//Saving the method from our costumer
customer.o = obj; // <- ???
customer.f = f; // <- ???
}
void someFunction(void) {
// here i want to call the method from the customer
customer.o->customer.f(); //<- ???
}
customer.cpp:
class AnyCustomerClass {
private:
Library lib;
public:
AnyCustomerClass() {
//< here the customer sets his method which I should call
lib.SetCallback(this, &AnyCustomerClass::callback());
}
callback() {
// do something
}
}
感谢您的帮助!
最佳答案
基本思想是,你定义一个抽象的回调类,它实际上被传递给你的接口(interface)。这个回调一个传递单个 int 参数的函数:
struct Callback {
virtual ~Callback(){}
virtual void operator()(int param)=0;
};
此类允许您的实现无需了解您需要回调的代码。当然,要调用一个类,您确实需要一个知道其目标的 Callback 实例。因此,您还可以提供一个模板化的子类,使您的库的用户可以轻松地将其中一个类中的方法绑定(bind)到通用回调的实例:-
template<class T>
class ClassCallback : public Callback {
T* _classPtr;
typedef void(T::*fncb)(int param);
fncb _cbProc;
public:
ClassCallback(T* classPtr,fncb cbProc):_classPtr(classPtr),_cbProc(cbProc){}
virtual void operator()(int param){
(_classPtr->*_cbProc)(param);
}
};
要从他们的类创建回调的实例,代码如下所示。调用也很简单:
struct CMyClass {
Library* _theLibrary;
CMyClass(Library* init):_theLibrary(init){
Callback* pCB = new ClassCallback<CMyClass>(&myClass,&CMyClass::OnCb);
_theLibrary->SetCallback(pCB);
}
void OnCb(int){
// callback triggered
}
void Run(){
_theLibrary->DoWork();
}
};
总结:Library.h 看起来像这样。定义抽象回调类、您的库类以及客户用来包装其类及其回调方法的模板化实用程序类:
// This is the header file what our customer gets
struct Callback {... };
class Library {
Callback* _pcb;
public:
void SetCallback(Callback* pcb){_pcb=pcb;}
void DoWork(){
int status=0;
(*pcb)(status);
}
~Library(){delete _pcb;}
};
template<class T> struct ClassCallback{ ... };
关于c++ - 在 C++ 中回调类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4919308/