【问题标题】:Qt signal and slots: are reference arguments copied?Qt 信号和槽:引用参数是否被复制?
【发布时间】:2017-06-30 10:41:46
【问题描述】:

在 qt 框架中,大多数库信号和槽都使用指针作为参数。我想知道,如果我创建一个将引用作为参数而不是指针的信号槽“结构”,会复制整个参数,还是像常规 c++ 引用一样只复制 4 个字节(32 位系统)?

我问这个是因为我在使用参考参数创建信号/槽方法时注意到了一些东西。然后当我connect 他们时,QTCreator 中的自动完成机制不会像他对指针参数那样用引用参数提示我。他用常规参数提示我。例如:

我创建了一个信号和槽:

...
signals:
     void mySignal(int& parameter);
private slots:
     void on_mySignal(int& parameter);

然后我尝试连接它们,Qt 没有在参数中添加 & 以供参考:

...
connect(this, SIGNAL(mySignal(int)), this, SLOT(on_mySignal(int)));

我必须手动更改为:

connect(this, SIGNAL(mySignal(int&)), this, SLOT(on_mySignal(int&)));

因此我想知道,参考是否甚至可以与信号/插槽一起使用?我将不胜感激。

【问题讨论】:

  • 你的前提是有缺陷的。常规 C++ 引用没有大小,因为它们不是对象。例如,您不能使用sizeof 来获取引用的大小。此外,您应该停止使用已弃用的信号/插槽语法。正确的语法是 connect(this, &Class::mySignal, this, &Class::on_mySignal);,这样您就不必担心了。
  • 我明白了,谢谢。但要回答主要问题:如果使用带有引用的信号/槽,是否会复制大量数据?
  • 我希望得到int 的副本,即使您指定了int &。您可以通过分配给插槽中的参数来测试它,并查看您传入的参数是否更改。
  • int 只是一个例子。在我的代码中,我有大型容器作为引用传入参数。这就是为什么它与我有关。也非常感谢您展示新的信号/插槽连接方法。确实很方便。
  • 请注意,QVector 等 Qt 容器在写入时使用复制,因此复制 QVectors 周围不会复制数据。如果您使用的是std::vectors,他们实际上会复制数据。

标签: c++ qt qt-signals slots


【解决方案1】:

如果您在同一个线程上发送和接收参考,默认情况下不会复制。如果您执行其他任何操作,包括发送/接收值或发送对另一个线程的引用,则会制作一个、两个甚至三个副本。

发生的情况取决于连接类型和 QT 需要知道引用在调用期间保持有效的保证。同一线程上的直接连接解析为一个简单的函数调用,因此底层数据几乎不会发生任何事情。然而,排队连接不能保证调用何时实际发生,因此 QT 将制作副本以保持数据完整性。 QT 隐式地对跨越线程边界的信号进行排队。

如果任一侧是按值传递,则 QT 复制数据以不影响底层对象的状态。

欲了解更多信息,have a look at this blog post

【讨论】:

  • 约翰,你不正确。复制不取决于线程,它取决于插槽连接类型。即使在同一线程中,引用参数也会在排队连接的情况下被复制。阅读 Qt 文档:doc.qt.io/qt-5/qt.html#ConnectionType-enum
  • 文档说,当连接排队时,参数被复制以存储在幕后的事件中。这是否意味着引擎测试参数是否为引用,如果是引用,则复制该值?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多