0

实际上,我在 Qt 中编程时一直在使用信号和插槽。信号和槽的主要用途是在 UI 交互中,例如,单击按钮会发送一个信号,该信号将调用槽来执行操作。我知道可以将信号和插槽用于非 gui 应用程序,例如服务器端应用程序。我寻找其他提供信号和插槽的库,并找到了boost库。这与我从 Qt 中学到的东西有些不同。然后我想知道信号和槽的真正用途是什么,因为我可以手动调用一个函数来在给定的时间执行一个动作。

例如在 boost 这里是信号/槽的一个例子:

#include <boost/signals2.hpp>
#include <iostream>

void mySlot(){
  std::cout << "I'm a slot" << std::endl;
}

void main(){
  boost::signals2::signal<void ()> sig;
  // Connecting the slot to the signal.
  sig.connect(mySlot);

  // Emitting a signal that will call mySlot 
  sig();

  return 0;
}

我可以简单地通过一个简单的调用来做同样的事情,mySlot()不是吗?

并不是让我想到的是,当我们尝试连接两个不同的插槽时,它们的调用顺序与连接顺序相同。如果第一个插槽被阻塞(尝试添加一个无限循环),第二个插槽将永远不会被调用!我猜它是一种存储函数地址然后迭代循环并逐个调用的向量!

信号和插槽背后的魔力是什么?还是只是开发人员的一种抽象?

先感谢您。

4

2 回答 2

3

简而言之:在我看来,主要思想是解耦。

在更长的情况下:例如,使用直接函数调用,您无法在通用功能和它的客户端之间建立一个完全独立的机构。与信号和插槽不同,会有紧密的耦合,因为您需要在满足您的标准的某些条件时知道确切调用哪些方法。

如果您想获得更多自由,就像许多其他 OOP 设计模式一样,您需要信号和插槽之类的东西。当一个通用组件(让我们称之为库)发出信号时,它不必知道(可能还不存在的)客户端接口。这使得通用组件足够灵活。

它还将更好地保持应用程序的响应能力,因为它不是直接调用,而是由 Qt 事件循环处理。可以说,您可以使用自定义线程机制来规避这一点,但这需要做更多的工作才能使其足够安全,而且您最终会在一天结束时做一些接近这一点的事情。

于 2013-12-29T21:06:01.770 回答
-1

信号和槽只是一种可以跨不同执行线程使用的通信机制。这是主要价值(尤其是在以 GUI 为中心的库中,例如 QT)。通常有 1 个线程负责绘制和管理应用程序的图形端以及 1 个或多个工作线程。使用信号和槽,可以从中抽象出来。如果您想使用直接函数调用,您需要同步线程,这会导致 GUI 端的性能和响应速度降低。

实际上,在一个执行线程中,使用信号和槽没有多大意义。当您想要在进程之间(在同一台机器上或不同机器之间)进行通信时,该值就会出现。

于 2013-12-29T21:11:53.143 回答