問題描述
我知道這個問題已經被問過很多次了,正因為如此,我很難深入挖掘這些問題并找到一個簡單的例子來說明什么是有效的.
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 標準中的功能,而不是使用靜態方法和傳遞指向類實例的指針: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
方法現在接受一個 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 << '
'; });
這篇關于使用類成員的 C++ 回調的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!