【问题标题】:How does Qt handle call-by-reference for signals and slots?Qt 如何处理信号和槽的引用调用?
【发布时间】:2015-12-23 09:05:19
【问题描述】:

我有几个关于信号和插槽的问题。我正在使用 Qt 4.8。

  1. 信号和槽必须是无效函数吗?信号当然不是函数,但它被声明为普通的成员函数。

  2. 我经常使用 call-by-const-reference 来避免创建过多的对象副本。我可以对信号和插槽使用按常量引用调用吗?发出信号后,发送的对象可能会超出范围。或者信号是否存储了所发送内容的副本?那么 call-by-const-reference 将与 call-by-value 相同。

  3. 如果槽操作它通过从发送者的引用调用获得的对象怎么办?发件人是否注意到这一点?

  4. 是否可以强制信号等待连接的插槽完成?我该怎么做?

【问题讨论】:

  • 这是 Qt4 “传统”信号还是 qt5 信号?
  • 我使用的是 Qt 4.8,但如果您能解释一下 Qt4 和 Qt5 之间的区别,我将不胜感激。
  • qt4和qt5的区别是另外一个话题,见doc.qt.io/qt-5/signalsandslots-syntaxes.html
  • “可以强制信号等待连接的插槽完成吗?我该怎么做?”这是同一线程内的信号/槽连接的默认设置(DirectConnection)。信号只是一个函数,它同步调用与其连接的所有槽。

标签: c++ qt pass-by-reference signals-slots


【解决方案1】:

首先我说的是Qt4连接(可能也适用于Qt5)

信号和槽必须是 void 函数吗

没有。如果您正常使用它们,具有返回值的信号和槽都将表现得好像它们是无效的。但是插槽 (using as normal function, binding, invoke method of metasystem) 和信号 (receive value from non void slots) 可以有高级用法

我可以将 call-by-const-reference 与信号和槽一起使用吗?

对qt没有任何意义。但是你仍然强制你的方法不改变它的参数。 Qt 中的连接被设计成数据被复制到一些连接类型中,除了 Qt::DirectConnection。在传统的 qt 连接中,程序员应该将 call-by-const-reference 签名完全视为按值调用签名。这是因为队列连接和线程之间的连接要求对象具有a public default constructor, a public copy constructor and a public destructor

Qt 使用implicit data sharing 解决了这个问题。例如,QImage 是一个轻量级对象,它在内部引用真实的像素数据,其大小可以任意大。

如果槽操作它通过引用调用获得的对象怎么办 来自发件人?发件人是否注意到这一点

如上所述引用调用将传递对象的副本。该对象首先被复制到函数外部,然后作为引用传递。但是,如果您传递一个与其副本共享数据的对象(例如共享指针),则对该对象的任何修改都可能影响所有副本。正如 peppe 在评论中指出的那样,大多数时候 Qt 将隐式共享与写入时复制相关联。这意味着在 QImage 的情况下,修改不会影响其他副本。

可以强制信号等待,直到连接的插槽 完成了?我该怎么做?

如果发送者和接收者都在同一个线程中,则使用连接类型Qt::DirectConnection,否则使用Qt::BlockingQueuedConnection。 如上所述,const 引用签名意味着 Qt::DirectConnection 不会复制数据,而 Qt::BlockingQueuedConnection 将复制数据。

【讨论】:

  • “这对 qt 没有任何意义。”按值与按 const ref. 在信号/槽签名中标准化。仍然使用 const ref. 可防止在直接连接中创建副本(默认值)。
  • “如上所述,引用调用将传递对象的副本。” - 它不会直接连接(默认)。作为非常量引用传递的对象与发送方传递的对象相同,因此接收方的修改对发送方可见。(如前所述,使用时直接连接)。
  • "但是如果你传递一个与其副本共享数据的对象(例如共享指针、QImage),对对象的任何修改都会影响所有副本。" QImage隐式共享的。修改一个浅拷贝会触发一个深拷贝(即“写时复制”);发件人仍然不会注意到自己副本中的修改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
相关资源
最近更新 更多