C++ callback using class member(使用类成员的 C++ 回调)
问题描述
我知道这个问题已经被问过很多次了,正因为如此,我很难深入挖掘这些问题并找到一个简单的例子来说明什么是有效的.
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++ 回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用类成员的 C++ 回调
基础教程推荐
- 这个宏可以转换成函数吗? 2022-01-01
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 我有静态或动态 boost 库吗? 2021-01-01
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 常量变量在标题中不起作用 2021-01-01
