2017-08-12 28 views
0

これはなぜ機能しませんか?Qtシグナル/スロットとC++ラムダ式

クラスは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. 
    }); 
} 

まず、スロットが呼び出されたときにバーが存在しなくなったと思います。それを修正するために、私は価値あるものを捉える必要があります。

私はそれを正しくしていますか?それを動作させる

CHANGES:

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

'Foo :: getBar'とは何ですか? – LogicStuff

+0

これはBar *を作成し、その親をFooに設定します。 –

+0

おそらく、信号が呼び出されたときに 'bar'はもはや有効ではないからです。 – Jepessen

答えて

2

barローカルポインタ変数です。 参照でキャプチャする場合は、[&bar]をキャプチャする場合と同じです。どのタイプにするかはBar**です。その後、barにアクセスしようとすると、Barへのポインタがキャプチャされた&barアドレスであると仮定してラムダで試行します。そして、それはローカル変数が破壊されたためではありません。タイプBarの実際のオブジェクトは、同じアドレスに置かれたままですが、このアドレスは、キャプチャ時に[&]で破損しています。したがって、キャプチャを[bar]に変更して、このポインタが見つかるアドレスではなくポインタを直接キャプチャするのは正しいです。

+0

明確な説明をありがとう、これは私が仮定したものです。 –