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 信号的许多客户端的开销?

似乎最好的方法是使用指向生成的 BIG_DATA 对象的指针,如果 QT 也没有尝试删除指针签名。

4

2 回答 2

3

签名规范化仅用于识别信号和槽。也就是说,如果你想知道connect()使用哪个信号或槽,你需要在那里传递规范化签名。但是您的信号和插槽的签名保持不变。如果您使用直接连接(这是单线程程序的默认设置),您的对象将不会被复制。

于 2013-08-06T21:56:37.200 回答
2

如果您使用排队连接,则无论如何都会复制您的结构(请参阅this)。

现在,如果您使用归一化信号,则可以在使用连接时最大限度地减少性能损失(请参阅此):

首先尝试按原样使用签名进行查找,只有在失败时才会调用 QMetaObject::normalizedSignature()。

这意味着,当使用非规范化的信号/槽签名时,您不仅要为 strcpy() 付费,还要为注定失败的第一次查找尝试付费。当然,连接通常在启动期间完成,分析器不会向您显示,但使用非规范化签名在此被牢牢地置于过早悲观化的领域。

但是,性能损失仅在使用连接时,而不是在发送信号时。并且连接通常只进行一次。因此我不会太担心。

为了避免结构复制,请使用引用。

于 2013-08-06T22:06:51.863 回答