【问题标题】:Qt signal/slots and C++ Lambda expressionQt 信号/槽和 C++ Lambda 表达式
【发布时间】:2017-08-12 12:03:06
【问题描述】:

为什么这不起作用?

类继承自 QObject

b 是子类。

bar 是 Foo 孩子。

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.
    });
}

【问题讨论】:

  • 什么是Foo::getBar
  • 它创建一个 Bar* 并将其父级设置为 Foo。
  • 可能是因为bar在调用信号时不再有效。
  • 请注意,您可以将“保护对象”作为第三个参数传递给connect(您的 lambda 然后是第四个),如果保护对象被破坏,它将破坏与 lambda 的连接。在这种情况下,您可能希望使用bar 作为守卫(需要Qt 5.2 或更高版本)。所以QObject::connect(bar, &Bar::s1, bar, [&]{....
  • bar 是 b child 而 b 是 Class child 我确定它存在。

标签: c++ qt lambda qt-signals qt-slot


【解决方案1】:

bar 是局部指针变量。 当您通过引用捕获时,它与捕获[&bar] 相同,输入Bar**。之后,您尝试在 lambda 中访问bar,假设指向Bar 的指针位于捕获的&bar 地址中。这不是真的,因为局部变量被破坏了。 Bar 类型的实际对象仍然位于同一地址,但在被[&] 捕获时,该地址已损坏。所以把capture改成[bar]这样直接捕获指针是正确的,而不是能找到这个指针的地址。

【讨论】:

  • 感谢您的清晰解释,这是我的假设。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
相关资源
最近更新 更多