c++ - lambda 函数和函数类型定义如何作为侦听器工作?
问题描述
我正在尝试从 Java 中制作相当于事件侦听器,但在 C++ 中。我的目标是,我可以从一个类中调用一个函数,这会触发我添加到这个类中的监听器。
我找到了以下链接,它为我提供了解决方案。
特此的问题是,我的程序在我尝试调用侦听器时立即崩溃。
我的代码结构如下:
class MessageHandler abstract
{
public:
typedef const std::function<void(int, std::string)> Handler;
void addHandler(Handler& handler) {
handlers.push_back(&handler);
}
private:
std::vector<Handler*> handlers;
protected:
void someFunction(int id, std::string message) {
for (auto& handler : handlers) {
(*handler)(id, message); //Here it will crash
}
}
};
正如您可能已经提到的,这是我从中派生一些子类的基类。然后这些子类调用我的“someFunction”代码。
我创建这些子类之一的类的结构如下:
class Server
{
private:
SubHandler handler;
void setHandlers() {
handler.addHandler([&](int id, std::string message) { executingFunction(id, message); });
}
void executingFunction(int id, std::string message) {
std::cout << "Listener Worked!" << std::endl;
//Not actually the code inside, but it doesn't matter, case I don't even get to this code
}
};
该程序在该行崩溃,我在其中循环我的侦听器并错误地调用它们:
“在位置 0x000000000000000010 读取时访问冲突。”
(这是翻译的,所以如果您将 Visual Studio 设置为英语,这不是您将收到的消息)
解决方案
您应该使用/permissive-
. 编译器应该拒绝你的代码。
void addHandler(Handler& handler) {
handlers.push_back(&handler);
}
你不应该能够向这个函数发送一个临时的,但你是!
// v----- This lambda is a temporary object --------------------------v
handler.addHandler([&](int id, std::string message) { executingFunction(id, message); });
在该行创建的 lambda 对象在语句完成后立即死亡。
// v---- pointer to the temporary.
handlers.push_back(&handler);
我的建议是删除指针并按std::function
值使用对象。它们被设计成这样使用:
// abstract is not a C++ keyword.
class MessageHandler /* abstract */
{
public:
// using instead of typedef and non const
using Handler = std::function<void(int, std::string)>;
void addHandler(Handler const& handler) { // const reference
// insert by value
handlers.push_back(handler);
}
private:
// no pointer here.
std::vector<Handler> handlers;
protected:
void someFunction(int id, std::string message) {
for (auto const& handler : handlers) {
handler(id, message); //Here it will not crash anymore
}
}
};
推荐阅读
- unity3d - Unity3D中,如何在UIElement面板的TextField中输入中文?
- html - 如何覆盖元素的 Bootstrap CSS?
- android - 自助服务终端应用程序更新和重启
- javascript - 如何为数组 JavaScript 中的每个对象分配一个随机整数
- javascript - 如果子字符串存在于字符串中,如何在子字符串之后获取下一个 3 个字符?
- php - 我必须使用 imagedestroy 吗?
- html - 如何将对象从组件拉到 html 角度?
- gcc - 为什么qemu执行mipsel的bin失败?
- date - 如何在 Dart/Flutter 中获取当前时间的 GMT 时间偏移值
- c# - 多个 DAC 和 SAC 调用的设计模式