读取 Lambda 回调后的访问冲突
Read Access Violation after Lambda-Callback
对于一个小的GUI,我首先想使用函数指针;在阅读了很多东西之后,我发现Lambda回调函数可能是更好的解决方案(?)。
我总是收到读取访问冲突,并猜测我缺少一些重要知识。 如果我在 lambda 调用中使用复制或引用构造函数没有区别 - 我仍然得到异常。
#include <iostream>
#include <functional>
using namespace std;
//=======================================================
class Button {
private:
function<void()> const &callback;
public:
Button(function<void()> const &c) : callback(c) {
cout << "created Button" << endl;
callback(); // THIS CALL WORKS FINE
}
void update() {
// if(clicked)...
callback(); // HERE I GET THE READ ACCESS VIOLATION
}
};
//=======================================================
class VideoPreview {
private:
Button *btn;
public:
VideoPreview() {
cout << "created VideoPreview" << endl;
btn = new Button([=]() {
//cout << "you clicked the button" << endl;
buttonClicked();
});
}
void update() { // "check the gui"
btn->update();
}
void buttonClicked() {
cout << "you clicked the button" << endl;
}
};
//=======================================================
void main() {
VideoPreview foo;
foo.update();
}
这里的问题是function<void()> const &callback;
不会std::function
延长从
btn = new Button([=]() {
//cout << "you clicked the button" << endl;
buttonClicked();
});
lambda 不是std::function
因此当您执行上述操作时,会生成临时std::function
。 然后,您可以使用callback
绑定到该临时变量const&
但成员变量不会延长它们绑定到的临时变量的生存期。 只有函数本地const&
才能获得该行为。 这意味着当你退出VideoPreview
的构造函数时,你留下了一个按钮,该按钮具有对已销毁对象的函数引用。
要解决此问题,只需按值存储callback
,例如
class Button {
private:
function<void()> callback;
public:
Button(function<void()> c) : callback(std::move(c)) {
cout << "created Button" << endl;
callback(); // THIS CALL WORKS FINE
}
void update() {
// if(clicked)...
callback(); // works now.
}
};
相关文章:
- 访问类C++ C 样式回调
- 为什么可以在没有实例变量的情况下访问静态回调方法中的静态成员变量?
- 使用参数的 C# 委托回调会导致从 DLL 调用时C++访问冲突
- 从触摸回调访问向量元素的方法时,不良访问错误
- 访问回调函数中的 QPushButton
- 如何从qmlregistersingletontype的回调中访问QML加载项目
- 从 NS3 中接收的回调访问 WiFiPhy
- 读取 Lambda 回调后的访问冲突
- 如何从回调方法访问自定义类成员
- 如何访问成员变量 sqlite 回调
- 如何访问带有静态回调的对象属性
- C到C#(从C#访问C DLL回调函数)
- 无法访问在 std 回调中传递的对象变量
- 访问作为WiFi侦听器回调成员函数一部分的类的成员
- C++如何通过回调方法访问成员变量
- 创建具有自动存储的自定义对象并推送回 std::vector 时访问冲突
- 从 ctypes 中的回调访问值
- Box2D冲突回调
- 来自c++的c#回调会导致访问冲突
- 当从c++代码发送回调到c#代码时,访问冲突读取位置0x00000004