Qt 和 Boost关于信号和槽的对比说明
对比
无论是 Qt 的实现方式还是 Boost 的实现方式,除了必须的定义信号和槽的类之外,都不需要额外的类。
两种实现都解决了类爆炸的问题。下面让我们对照着来看一下我们前面的分析。
-
两个不同的术语以及各自的动作:信号和槽;
-
在一个地方(信号)可以连接零个或者多个回调函数(槽)同时也是多对多的,一对多,多对多;
-
焦点在于连接本身,而不是提供者或者消费者;
-
不需要手工为了一个连接创建新的类;
-
连接仍旧是类型安全的。
这五点是信号槽系统的核心,Qt 和 boost 都拥有这些特性。
下面则是二者的不同之处:
Boost.Signals | Qt Signals 和 Slots | |
信号 | 一个信号就是一个对象 全局的、局部的或者是成员对象 | 信号只能是成员函数 |
调用 | 发出信号类似于函数调用 任何能够访问到信号对象的代码都可以发出信号 | 发出信号类似于函数调用 Qt 提供了一个 emit 关键字来完成这个操作 只有信号的拥有者才能发出信号 |
槽 | 槽是任何可被调用的函数或者函数对象 | 槽是经过特别设计的成员函数 |
返回值 | 可以有返回值?,返回值可以在多个槽中使用 | 没有返回值 |
同步异步 | 同步 | 同步或(直连)者异步(队列) |
线程安全 | 非线程安全? | 线程安全,可以跨线程使用 |
信号断开 | 当且仅当槽是可追踪的时候?,槽被销毁时,连接自动断开 | 槽被销毁时,连接都会自动断开(因为所有槽都是可追踪的) |
类型安全 | 类型安全(编译器检查) | 类型安全(运行期检查) |
参数列表 | 参数列表必须完全一致 | 槽可以忽略信号中多余的参数(信号的参数可以比槽多) |
信号、槽可以是模板 | 信号、槽不能是模板 | |
底层实现 | C++ 直接实现 | 通过由 moc 生成的元对象实现(moc 以及元对象系统都是 C++ 直接实现的) |
内省 | 没有内省机制 | 可以通过内省发现 可以通过元对象调用 连接可以从资源文件中自动推断出 |
?都是有疑问的地方。目前还未理解
最重要的是,Qt 的信号槽机制已经深深地植入到框架之中,成为不可分割的一部分。它们可以使用 Qt 专门的开发工具,例如 QtCreator,通过拖拽的方式很轻松的创建、删除、修改。它们甚至可以通过动态加载资源文件,由特定命名的对象自动动态生成。这些都是 boost 作为一个通用库所不可能提供的。
-----------------------------------------------------------------------------------------------------------------------------------