Сигнал / слоты Qt и лямбда-выражение C++

Почему это не работает?

Класс наследовать от QObject

б класс ребенка.

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

1 ответ

Решение

bar является локальной переменной указателя. Когда вы захватываете по ссылке, это так же, как захватывать [&bar]какой тип это Bar**, После этого вы пытаетесь получить доступ к bar в лямбда при условии, что указатель на Bar находится в плену &bar адрес. И это не так, потому что локальная переменная была уничтожена. Фактический объект типа Bar остается расположенным по тому же адресу, но этот адрес поврежден при захвате [&], Поэтому правильно изменить захват на [bar] и, таким образом, захватывает указатель напрямую, а не адрес, где этот указатель может быть найден.

Другие вопросы по тегам