【问题标题】:What benefits does QT get with normalized signatureQT 使用规范化签名有什么好处
【发布时间】:2013-08-08 02:26:44
【问题描述】:

我读到 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 也没有尝试删除指针签名。

【问题讨论】:

  • connect 是函数声明还是函数调用(或兼具两者的古怪宏)?它看起来像一个函数调用。您不要将参数类型放在函数调用中。 SIGNAL呢?
  • SIGNAL() 和 SLOT() 只是将参数转换为 char 数组的宏。 connect() 是一个函数调用。

标签: c++ qt


【解决方案1】:

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

现在,如果您使用归一化信号,您可以在使用连接 (see this) 时将性能损失降至最低:

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

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    猜你喜欢
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 2010-09-20
    相关资源
    最近更新 更多