C ++类的成员callback简单的例子

我知道这已经被问了很多次了,因此很难深入挖掘,find一个简单的例子。

我有这个,这很简单,它适用于MyClass

 #include <iostream> using std::cout; using std::endl; class MyClass { public: MyClass(); static void Callback(MyClass* instance, int x); private: int private_x; }; class EventHandler { public: void addHandler(MyClass* owner) { cout << "Handler added..." << endl; //Let's pretend an event just occured owner->Callback(owner,1); } }; EventHandler* handler; MyClass::MyClass() { private_x = 5; handler->addHandler(this); } void MyClass::Callback(MyClass* instance, int x) { cout << x + instance->private_x << endl; } int main(int argc, char** argv) { handler = new EventHandler(); MyClass* myClass = new MyClass(); } class YourClass { public: YourClass(); static void Callback(YourClass* instance, int x); }; 

如何重写,所以EventHandler::addHandler()将与MyClassYourClass 。 我很抱歉,但这只是我的大脑的工作方式,我需要看一个简单的例子,以便我能理解为什么/如何工作。 如果你现在有一个最喜欢的方式来展示它,请将该代码标记出来并将其发回。

[编辑]

已经回答了,但答复被删除之前,我可以把复选标记。 我的答案是一个模板函数。 更改addHandler到这个…

 class EventHandler { public: template<typename T> void addHandler(T* owner) { cout << "Handler added..." << endl; //Let's pretend an event just occured owner->Callback(owner,1); } }; 

而不是使用静态方法并传递指向类实例的指针,可以使用新的C ++ 11标准中的std::functionstd::functionstd::bind

 #include <functional> class EventHandler { public: void addHandler(std::function<void(int)> callback) { cout << "Handler added..." << endl; // Let's pretend an event just occured callback(1); } }; 

addHandler方法现在接受一个std::function参数,而这个“函数对象”没有返回值,并且接受一个整数作为参数。

要将其绑定到特定的函数,可以使用std::bind

 class MyClass { public: MyClass(); // Note: No longer marked `static`, and only takes the actual argument void Callback(int x); private: int private_x; }; MyClass::MyClass() { using namespace std::placeholders; // for `_1` private_x = 5; handler->addHandler(std::bind(&MyClass::Callback, this, _1)); } void MyClass::Callback(int x) { // No longer needs an explicit `instance` argument, // as `this` is set up properly cout << x + private_x << endl; } 

添加处理程序时,您需要使用std::bind ,因为您明确需要指定其他隐式的this指针作为参数。 如果你有一个独立的函数,你不必使用std::bind

 void freeStandingCallback(int x) { // ... } int main() { // ... handler->addHandler(freeStandingCallback); } 

让事件处理程序使用std::function对象也可以使用新的C ++ 11 lambda函数 :

 handler->addHandler([](int x) { std::cout << "x is " << x << '\n'; }); 

你想要做的是做一个接口来处理这个代码,所有的类都实现这个接口。

 class IEventListener{ public: void OnEvent(int x) = 0; // renamed Callback to OnEvent removed the instance, you can add it back if you want. }; class MyClass :public IEventListener { ... void OnEvent(int x); //typically such a function is NOT static. This wont work if it is static. }; class YourClass :public IEventListener { 

请注意,对于这个工作,“callback”函数是非静态的, 我相信是一个改进。 如果你希望它是静态的,你需要这样做JaredCbuild议模板。

这是一个简洁的版本,可以与类方法callback和常规的函数callback一起使用。 在这个例子中,为了显示如何处理参数,callback函数有两个参数: boolint

 class Caller { template<class T> void addCallback(T* const object, void(T::* const mf)(bool,int)) { using namespace std::placeholders; callbacks_.emplace_back(std::bind(mf, object, _1, _2)); } void addCallback(void(* const fun)(bool,int)) { callbacks_.emplace_back(fun); } void callCallbacks(bool firstval, int secondval) { for (const auto& cb : callbacks_) cb(firstval, secondval); } private: std::vector<std::function<void(bool,int)>> callbacks_; } class Callee { void MyFunction(bool,int); } //then, somewhere in Callee, to add the callback, given a pointer to Caller `ptr` ptr->addCallback(this, &Callee::MyFunction); //or to add a call back to a regular function ptr->addCallback(&MyRegularFunction); 

这限制了C ++ 11特定的代码在类Caller中的addCallback方法和私有数据。 至less对我来说,这可以最大限度地减less在实施过程中出错的几率。

MyClassYourClass都可以从具有抽象(虚拟) Callback方法的SomeonesClass派生。 您的SomeonesClass将接受SomeonesClassMyClasstypes的对象, YourClass可以重写Callback以提供其具体的callback行为的实现。

如果你有不同参数的callback,你可以使用如下模板:
//编译时使用:g ++ -std = c ++ 11 myTemplatedCPPallback.cpp -o myTemplatedCPPallbackApp

 #include <functional> // c++11 #include <iostream> // due to: cout using std::cout; using std::endl; class MyClass { public: MyClass(); static void Callback(MyClass* instance, int x); private: int private_x; }; class OtherClass { public: OtherClass(); static void Callback(OtherClass* instance, std::string str); private: std::string private_str; }; class EventHandler { public: template<typename T, class T2> void addHandler(T* owner, T2 arg2) { cout << "\nHandler added..." << endl; //Let's pretend an event just occured owner->Callback(owner, arg2); } }; MyClass::MyClass() { EventHandler* handler; private_x = 4; handler->addHandler(this, private_x); } OtherClass::OtherClass() { EventHandler* handler; private_str = "moh "; handler->addHandler(this, private_str ); } void MyClass::Callback(MyClass* instance, int x) { cout << " MyClass::Callback(MyClass* instance, int x) ==> " << 6 + x + instance->private_x << endl; } void OtherClass::Callback(OtherClass* instance, std::string private_str) { cout << " OtherClass::Callback(OtherClass* instance, std::string private_str) ==> " << " Hello " << instance->private_str << endl; } int main(int argc, char** argv) { EventHandler* handler; handler = new EventHandler(); MyClass* myClass = new MyClass(); OtherClass* myOtherClass = new OtherClass(); }