信号によって送信されるオブジェクトの削除、信号内のオブジェクトの所有権、QT

StackOverflow https://stackoverflow.com/questions/3183826

質問

ここで、私の信号宣言:

signals:
    void mySignal(MyClass *);

そして私がそれをどのように使用しているか:

MyClass *myObject=new myClass();
emit mySignal(myObject);

ここに私の問題があります:myobjectの削除の責任者は誰ですか:

  1. 送信者コード、Myobjectが使用される前に削除された場合はどうなりますか?ぶら下がっているポインター

  2. 信号に接続されたスロット、スロットがなく、信号に接続されているスロットが複数ない場合はどうなりますか?メモリリークまたはダングリングポインター

QTは、ビルドイン信号でこの状況をどのように管理しますか?内部参照カウントを使用していますか?

あなたのベストプラクティスは何ですか?

役に立ちましたか?

解決

信号を必要な数のスロットで接続できます。そのため、これらのスロットのいずれも、オブジェクトでやりたくないことを行うことができないことを確認する必要があります。

  • ポインターをパラメーターとして渡すことに決めた場合、あなたが説明する問題、メモリ管理を実行します - ここでは、あなたが割り当て/削除に対処するためのポリシーを確立する必要があるので、あなたのために誰もあなたのためにできません。これに対処する方法に関するいくつかのアイデアに com 世界。
  • パラメーターを参照として渡すことにした場合、メモリ管理について心配する必要はありませんが、スロットが予期しない方法でオブジェクトを変更することについてのみです。 IDEEAは、必要な場合を除き、ポインターを渡すことではありません。代わりに、可能であれば参照を使用します。
  • あなたが渡すことにした場合 const 参照して、接続タイプに応じて、QTはあなたのためにオブジェクトの値を渡します(参照してください これ いくつかの詳細については)
  • 問題を避けて価値を渡す:)

これも参照してください 質問 信号でポインターを渡すことについてのいくつかの考えのために。

他のヒント

最初の質問では、使用してください qpointer

あなたの2番目の質問のために、

私がはっきりと理解していれば、あなたが送っていても myObject, 、 君 まだ参照があります myObject 信号を発しているクラスで。それでは、それはどのようにしてメモリリークまたはダングリングポインターになるのでしょうか?あなたはまだすることができます アクセス myObject 放出されたクラスからそうではありませんか?

明確なことを願っています。

編集 :

あなたのコメントから、私はあなたがスロット内のオブジェクトをリリース/削除していると信じています。今、私はあなたの問題が、(メモリリリース)スロットが1回、2回呼び出された場合、またはまったく呼び出されない場合、あなたの問題だと思います。

そのためにqpointerを使用できます。 QTドキュメントから、

ガード付きポインター(QPointer)ポインターを保存する必要があるときはいつでも便利です QObject それは他の誰かが所有しているため、あなたがまだそれを参照している間に破壊される可能性があります。有効性についてポインターを安全にテストできます。

QTドキュメント自体の例、

     QPointer<QLabel> label = new QLabel;
     label->setText("&Status:");
     ...
     if (label)
         label->show();

説明はこのように続きます。

その間にQLabelが削除された場合、ラベル変数は無効なアドレスの代わりに0を保持し、最後の行は実行されません。 ここでqlabelがあなたになります MyClass ラベルはあなたです myObject. 。そして、それを使用する前にチェックします 無効.

1):送信者は注意してください。 (キューの代わりに)信号を同期して送信するとき、受信者が受信したときにオブジェクトはまだ生きています。受信者がそれを保存する必要がある場合、QPointerのみが役立ちますが、MyClassはQObjectから派生する必要があります。これはコンテキストから間違っています。とにかく、それは一般的な生涯の問題であり、非常に信号/スロット固有ではありません。

代替品:値クラスを使用して、const Referenceで送信します。 MyClassがサブクラスを持つことができる場合は、const qsharedpointerを渡します&

deletelaterについて:deletelater()はここでは役に立ちません。キューに囲まれた接続がより安全になり、直接接続のために違いはありません。 deletelater()が登場する1つの用途は、受信者が送信者を削除する必要がある場合です。その後、常にdeletelater()を使用する必要があるため、送信者は自分がやっていることを完了できます。

単語(申し分なく、機能名) - deletelater():)すべてのqobjectsにはそれがあります。削除のオブジェクトをマークし、これは次のイベントループアップデートで発生します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top