web-dev-qa-db-ja.com

Qtでプライベートスロットの代わりにパブリックスロットを使用すると、違いはありますか?

C++では、publicは、オブジェクトが表示されているどこからでもアクセスできるメンバーを意味します。privateは、メンバーが同じクラスの他のメンバー内またはその友達からのみアクセスできることを意味します。

しかしQtでは、private slotsおよびpublic slotsは存在しないようです。最近、Qtを書き始めて、private slots常に。

誰かがpublic slots代わりに。だから今、私は困惑しています。 Qtのドキュメントに参照情報が見つかりません。

2つのタイプの実際の違いは何ですか?

27
罗泽轩

Qtドキュメント から:

スロットは通常のメンバー関数であるため、直接呼び出された場合、通常のC++ルールに従います。ただし、スロットとして、シグナルスロット接続を介して、アクセスレベルに関係なく、任意のコンポーネントから呼び出すことができます。これは、任意のクラスのインスタンスから発信された信号により、無関係なクラスのインスタンスでプライベートスロットが呼び出される可能性があることを意味します。

これの意味:別のクラスからは、プライベートスロットを関数として呼び出すことはできませんが、そのプライベートスロットに接続されたシグナルを発信すると、呼び出すことができます。

31
user2448027

プライベート/パブリックアクセスはコンパイル時にコンパイラによって「チェック」されますが、シグナルスロット接続は実行時に実行され、スロットはいくつかのQMetaObjectメカニズム(たとえば invokeMethod のようなもの)によって呼び出されます。

違いはこれです:プライベートスロットprivate通常として呼び出された場合メンバー関数ですが、信号を呼び出すには常に「public」です。これは、スロットは概念的にはパブリックインターフェイスであるため、その主な目的はオブジェクト間の通信であるためです。

関連する「奇妙な」ものについての別の例は、メソッドの呼び出しに使用されるポインターの静的型でパブリックである場合のプライベート仮想関数の呼び出しです。

14
Zlatomir

@ user2448027答えは正しいですが、Qtの設計パターンに不足している点があります:異なるアプリケーション of private slots vs public slots

スロットをprivateにすることにより、オブジェクトのユーザーに、メンバーアクセス演算子(.または->)ではなく、connect関数を使用してスロットを呼び出すように強制します。

クラスのスロットの1つに遅いコードまたはブロックしているコードがあるとします。クラスのユーザーは、作成されたオブジェクトを別のスレッドに移動することを期待しているため、このオブジェクトの所有者(GUIまたはGUIに関連するオブジェクト)は、このスロットを呼び出してもフリーズまたはブロックしません。ここが要点です。スロットが.または->演算子によって直接呼び出された場合、ブロックされます。呼び出し元メソッドの現在のスレッドはスロットを使用するため、パブリックスロットを使用する場合にのみ発生します。解決策は、スロットをprivateにすることです。そのため、ユーザーはconnectでのみ呼び出すことができ、メンバーアクセス演算子(.または->)では呼び出せません。

結論:

  • ブロッキングスロットがある場合は、それらをprivateにします。
  • スロットをオブジェクトプロパティの簡単な設定として使用する場合は、publicにします。
  • 戻り値または一定でない参照引数を持ついくつかのメソッドが必要な場合、それらをスロットにしないでください(それはナンセンスです)、publicのみで十分です。
5
AMCoded