2

QT がシグナル/スロット メカニズムに署名の正規化プロセスを適用することを読みました。MOC ジェネレーターは基本的に、シグナル/スロットから const 参照修飾子を削除し、値で渡すだけです。

BIG_DATA と呼ばれる大きなデータ構造を頻繁に生成するクラスがあり、他のいくつかのクラスは、このデータ構造が発行されるたびにキャッチする必要があります。

struct BIG_DATA
{
    // very big data
};

class DataGenerator
{
    // some methods which generate BIG_DATA

   signals:
      void data_updated(const BIG_DATA &);
};

私がやること :

connect(&data_generator_object, SIGNAL(data_updated(const BIG_DATA &)), this, SLOT(catch_new_data(const BIG_DATA &)));

QT の機能:

connect(&data_generator_object, SIGNAL(data_updated(BIG_DATA)), this, SLOT(catch_new_data(BIG_DATA)));

では、ここで const 参照修飾子を削除する利点は何ですか? BIG_DATA 全体を data_updated シグナルの多くのクライアントにコピーするオーバーヘッドをどうするか?

QTがポインター署名も削除しようとしない場合、生成されたBIG_DATAオブジェクトへのポインターを使用するのが最善の方法のようです。

4

2 に答える 2

3

署名の正規化は、信号とスロットを識別するためにのみ使用されます。つまり、connect()どのシグナルまたはスロットを使用するかを知りたい場合は、正規化された署名をそこに渡す必要があります。ただし、シグナルとスロットの署名は変更されません。直接接続 (シングルスレッド プログラムのデフォルト) を使用する場合、オブジェクトはコピーされません。

于 2013-08-06T21:56:37.200 に答える
2

キュー接続を使用している場合、構造はとにかくコピーされます (これを参照してください)。

ここで、正規化されたシグナルを使用すると、接続を使用しているときにパフォーマンスへの影響を最小限に抑えることができます (これを参照してください)。

ルックアップは最初に署名をそのまま使用して試行され、それが失敗した場合にのみ QMetaObject::normalizedSignature() が呼び出されます。

つまり、正規化されていないシグナル/スロット シグネチャを使用すると、strcpy() だけでなく、失敗する運命にある最初のルックアップ試行にも料金がかかります。確かに、接続は通常起動時に行われ、プロファイラーには表示されませんが、正規化されていない署名を使用することは、時期尚早の悲観の領域にしっかりと置かれます.

ただし、パフォーマンスへの影響は接続を使用する場合のみであり、シグナルを送信する場合ではありません。そして、接続は通常一度だけ行われます。したがって、あまり心配する必要はありません。

構造のコピーを回避するには、参照を使用します。

于 2013-08-06T22:06:51.863 に答える