使用类成员的C ++回调 [英] C++ callback using class member
问题描述
我知道这个问题已经问了很多遍了,因此很难深入研究这个问题,并找到一个简单的例子来说明什么是有效的.
I know this has been asked so many times, and because of that it's difficult to dig through the cruft and find a simple example of what works.
我已经知道了,它很简单,并且适用于MyClass
...
I've got this, it's simple and it works for 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()
与MyClass
和YourClass
一起使用.抱歉,这只是我的大脑运作的方式,我需要先了解一个简单的运作方式示例,然后才能理解其运作方式.如果您有一种最喜欢的方法来进行这项工作,现在是时候炫耀一下,请标记该代码并将其发布回去.
How can that be rewritten so EventHandler::addHandler()
will work with both MyClass
and YourClass
. I'm sorry but it's just the way my brain works, I need to see a simple example of what works before I can comprehend why/how it works. If you've got a favorite way to make this work now's the time to show it off, please markup that code and post it back.
已回答,但答案被删除,我无法打勾. 在我的情况下,答案是模板函数.将addHandler更改为此...
It was answered but the answer was deleted before I could give the checkmark. The answer in my case was a templated function. Changed addHandler to this...
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标准中的功能,而不必使用静态方法并传递指向类实例的指针, http://en.cppreference.com/w/cpp/utility/functional/function> std::function
和
Instead of having static methods and passing around a pointer to the class instance, you could use functionality in the new C++11 standard: std::function
and std::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
参数,并且此函数对象"没有返回值,并使用整数作为参数.
The addHandler
method now accepts a std::function
argument, and this "function object" have no return value and takes an integer as argument.
要将其绑定到特定功能,请使用std::bind
:
To bind it to a specific function, you use 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
:
You need to use std::bind
when adding the handler, as you explicitly needs to specify the otherwise implicit this
pointer as an argument. If you have a free-standing function, you don't have to use std::bind
:
void freeStandingCallback(int x)
{
// ...
}
int main()
{
// ...
handler->addHandler(freeStandingCallback);
}
让事件处理程序使用std::function
对象,还可以使用新的C ++ 11 lambda函数:
Having the event handler use std::function
objects, also makes it possible to use the new C++11 lambda functions:
handler->addHandler([](int x) { std::cout << "x is " << x << '\n'; });
这篇关于使用类成员的C ++回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!