2017-08-12 7 views
0

Pourquoi cela ne fonctionne pas?Signal Qt/slots et expression Lambda C++

Hériter de classe de QObject

b est adapté aux enfants de classe.

La barre est Foo enfant.

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

Comme première estimation, je pense que la barre n'est plus exister lorsque la fente est appelée. pour le corriger, j'ai besoin de capturer en valeur.

Est-ce que je comprends bien?

CHANGEMENTS À L'OEUVRE:

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

Qu'est-ce que 'Foo :: getBar'? – LogicStuff

+0

crée une barre * et définit son parent sur Foo. –

+0

Probablement parce que 'bar' n'est plus valide lorsque le signal est appelé. – Jepessen

Répondre

2

bar est variable pointeur local. Lorsque vous capturez par référence, la capture est la même que pour [&bar], qui le saisit Bar**. Après cela, vous essayez d'accéder à bar en lambda en supposant que le pointeur vers Bar est situé par l'adresse &bar capturée. Et ce n'est pas vrai parce que la variable locale a été détruite. L'objet réel de type Bar est reste situé par la même adresse, mais cette adresse est corrompue lors de la capture par [&]. Il est donc correct de changer la capture en [bar] et ainsi de capturer le pointeur directement, pas l'adresse où ce pointeur peut être trouvé.

+0

Merci pour l'explication claire, c'est ce que j'ai supposé. –