我有一个带简单按钮的简单事件系统。这个系统由std :: function list驱动,里面有指定的lambdas。
这是完整按钮类:
class Button {
private:
Square square;
Text label;
bool hovered = false;
std::function <void ()> on_mouse_enter;
std::function <void ()> on_mouse_leave;
public:
Button (const Square& SQUARE, const Text& LABEL):
square {SQUARE},
label {LABEL}
{
on_mouse_enter = [this] () {
square.set_color(1, 1, 1);
};
on_mouse_leave = [this] () {
square.set_color(0, 0, 0);
};
}
std::function <void (const Render&)> get_rendering() {
return [this] (const Render& RENDER) {
RENDER.draw(square);
RENDER.draw(label);
};
}
std::function <void (const Point&)> get_updating() {
return [this] (const Point& CURSOR) {
if (not hovered) {
if (is_including(square, CURSOR)) {
hovered = true;
if (on_mouse_enter)
on_mouse_enter();
}
} else
if (not is_including(square, CURSOR)) {
hovered = false;
if (on_mouse_leave)
on_mouse_leave();
}
};
}
};
我将这样的按钮添加到事件管理器中,如下所示:
Button button {/*SOME_PARAMS_HERE*/};
mngr.push_to_render(button.get_render());
mngr.push_to_updater(button.get_updater());
它完美无缺, on_mouse_enter 和 on_mouse_leave 按预期工作。
但是,如果我使用STL容器包装器执行某些操作,请执行以下操作:
std::list <Button> sb;
sb.emplace_back(Button {/*SOME_PARAMS_HERE*/});
mngr.push_to_render(sb.back().get_render());
mngr.push_to_updater(sb.back().get_updater());
整件事正在崩溃。 on_mouse_enter 和 on_mouse_leave 无法正常工作。
通过输出调试消息,我可以看到 on_mouse_enter 中的 和 on_mouse_leave 访问的正方形不是它们应该是的正方形,接下来我看到这个不是它应该的样子。
这种捕获有什么问题以及如何解决?
答案 0 :(得分:5)
如果要复制,请不要捕获this
。无论你捕获什么,你都负责管理终生。
其次,指向传递给进入/离开的按钮的指针很有意义。
std::function<void(Button*)> on_mouse_enter;
std::function<void(Button*)> on_mouse_leave;
然后我们有:
on_mouse_enter = [] (Button* but) {
but->square.set_color(1, 1, 1);
};
on_mouse_leave = [] (Button* but) {
but->square.set_color(0, 0, 0);
};
并且复制构造函数不再为您指向不同的this
。
最后,当您致电on_mouse_enter
时,请传递this
。