2017-08-12 3 views
0

Warum funktioniert das nicht?Qt-Signal/Slots und C++ Lambda-Ausdruck

Klasse vererben QObject

b Klasse Kind.

Bar ist Foo Kind.

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

Als erste Rate denke ich, dass die Leiste nicht mehr existiert, wenn der Steckplatz aufgerufen wird. um es zu korrigieren, muss ich nach Wert erfassen.

Werde ich es richtig machen?

Veränderungen, die es funktioniert:

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

Was ist 'Foo :: getBar'? – LogicStuff

+0

es erstellt einen Balken * und legen Sie seinen Eltern zu Foo. –

+0

Wahrscheinlich, weil 'bar' nicht mehr gültig ist, wenn das Signal aufgerufen wird. – Jepessen

Antwort

2

bar lokalen Zeigervariable ist. Wenn Sie per Referenz erfassen, ist es das gleiche wie zu erfassen [&bar], die es eingeben Bar**. Danach versuchen Sie, in Lambda auf bar zuzugreifen, unter der Annahme, dass der Zeiger auf Bar von erfasste Adresse &bar befindet. Und es ist nicht wahr, weil die lokale Variable zerstört wurde. Das eigentliche Objekt vom Typ Bar bleibt an der gleichen Adresse liegen, aber diese Adresse ist bei der Erfassung durch [&] beschädigt. Es ist also richtig, die Aufnahme in [bar] zu ändern und somit den Zeiger direkt zu erfassen, nicht die Adresse, wo dieser Zeiger gefunden werden kann.

+0

Vielen Dank für die klare Erklärung, das ist, was ich angenommen habe. –