gpt4 book ai didi

c++ - Lambda 回调后读取访问冲突

转载 作者:可可西里 更新时间:2023-11-01 18:27:48 26 4
gpt4 key购买 nike

对于小型 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 绑定(bind)到那个临时的但是const&成员变量不会延长它们绑定(bind)到的临时变量的生命周期。仅在本地运行 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++ - Lambda 回调后读取访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54405739/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com