Qt signal/slots 和 C++ Lambda 表达式
Qt signal/slots and C++ Lambda expression
为什么这不起作用?
Class继承自QObject
b 是 Class child.
bar 是 Foo child.
void Class::method(Foo& b) {
Bar* bar = b.getBar();
QObject::connect(bar, &Bar::s1, [&]{
auto x = bar->x(); // this line throw an exception read access violation.
});
}
作为第一个猜测,我认为调用插槽时该栏已不存在。要更正它,我需要按值捕获。
我做对了吗?
让它发挥作用的改变:
void Class::method(Foo& b) {
Bar* bar = b.getBar();
QObject::connect(bar, &Bar::s1, [bar]{
auto x = bar->x(); // this line throw no more exceptions and work as expected.
});
}
bar
是局部指针变量。
当您通过引用捕获时,它与捕获 [&bar]
相同,类型为 Bar**
。之后,您尝试访问 lambda 中的 bar
,假设指向 Bar
的指针位于捕获的 &bar
地址中。事实并非如此,因为局部变量已被破坏。 Bar
类型的实际对象仍位于同一地址,但在 [&]
捕获时该地址已损坏。所以把capture改成[bar]
是正确的,直接捕获指针,而不是这个指针所在的地址。
为什么这不起作用?
Class继承自QObject
b 是 Class child.
bar 是 Foo child.
void Class::method(Foo& b) {
Bar* bar = b.getBar();
QObject::connect(bar, &Bar::s1, [&]{
auto x = bar->x(); // this line throw an exception read access violation.
});
}
作为第一个猜测,我认为调用插槽时该栏已不存在。要更正它,我需要按值捕获。
我做对了吗?
让它发挥作用的改变:
void Class::method(Foo& b) {
Bar* bar = b.getBar();
QObject::connect(bar, &Bar::s1, [bar]{
auto x = bar->x(); // this line throw no more exceptions and work as expected.
});
}
bar
是局部指针变量。
当您通过引用捕获时,它与捕获 [&bar]
相同,类型为 Bar**
。之后,您尝试访问 lambda 中的 bar
,假设指向 Bar
的指针位于捕获的 &bar
地址中。事实并非如此,因为局部变量已被破坏。 Bar
类型的实际对象仍位于同一地址,但在 [&]
捕获时该地址已损坏。所以把capture改成[bar]
是正确的,直接捕获指针,而不是这个指针所在的地址。