問(wèn)題描述
我知道這個(gè)問(wèn)題已經(jīng)被問(wèn)過(guò)很多次了,正因?yàn)槿绱耍液茈y深入挖掘這些問(wèn)題并找到一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明什么是有效的.
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.
我知道了,它很簡(jiǎn)單,適用于 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);
};
如何重寫(xiě),以便 EventHandler::addHandler()
可以與 MyClass
和 YourClass
一起使用.我很抱歉,但這只是我大腦的工作方式,我需要先看看一個(gè)簡(jiǎn)單的例子,然后才能理解它為什么/如何工作.如果您有最喜歡的方法來(lái)完成這項(xiàng)工作,現(xiàn)在是時(shí)候展示它了,請(qǐng)標(biāo)記該代碼并將其發(fā)回.
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.
有人回答了,但在我打勾之前答案就被刪除了.就我而言,答案是模板化函數(shù).將 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 標(biāo)準(zhǔn)中的功能,而不是使用靜態(tài)方法和傳遞指向類(lèi)實(shí)例的指針:std::function
和 std::bind
:
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
方法現(xiàn)在接受一個(gè) std::function
參數(shù),并且這個(gè)函數(shù)對(duì)象"沒(méi)有返回值并且接受一個(gè)整數(shù)作為參數(shù).
The addHandler
method now accepts a std::function
argument, and this "function object" have no return value and takes an integer as argument.
要將其綁定到特定函數(shù),請(qǐng)使用 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;
}
您需要在添加處理程序時(shí)使用 std::bind
,因?yàn)槟枰鞔_指定其他隱式的 this
指針作為參數(shù).如果你有一個(gè)獨(dú)立的函數(shù),你就不必使用 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
對(duì)象,還可以使用新的 C++11 lambda 函數(shù):
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 << '
'; });
這篇關(guān)于使用類(lèi)成員的 C++ 回調(diào)的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!