對比
無論是 Qt 的實現方式還是 Boost 的實現方式,除了必須的定義信號和槽的類之外,都不需要額外的類。
兩種實現都解決了類爆炸的問題。下面讓我們對照着來看一下我們前面的分析。
-
兩個不同的術語以及各自的動作:信號和槽;
-
在一個地方(信號)可以連接零個或者多個回調函數(槽)同時也是多對多的,一對多,多對多;
-
焦點在於連接本身,而不是提供者或者消費者;
-
不需要手工為了一個連接創建新的類;
-
連接仍舊是類型安全的。
這五點是信號槽系統的核心,Qt 和 boost 都擁有這些特性。
下面則是二者的不同之處:
Boost.Signals | Qt Signals 和 Slots | |
信號 | 一個信號就是一個對象 全局的、局部的或者是成員對象 |
信號只能是成員函數 |
調用 | 發出信號類似於函數調用 任何能夠訪問到信號對象的代碼都可以發出信號 |
發出信號類似於函數調用 Qt 提供了一個 emit 關鍵字來完成這個操作 只有信號的擁有者才能發出信號 |
槽 | 槽是任何可被調用的函數或者函數對象 | 槽是經過特別設計的成員函數 |
返回值 | 可以有返回值?,返回值可以在多個槽中使用 | 沒有返回值 |
同步異步 | 同步 | 同步或(直連)者異步(隊列) |
線程安全 | 非線程安全? | 線程安全,可以跨線程使用 |
信號斷開 | 當且僅當槽是可追蹤的時候?,槽被銷毀時,連接自動斷開 | 槽被銷毀時,連接都會自動斷開(因為所有槽都是可追蹤的) |
類型安全 | 類型安全(編譯器檢查) | 類型安全(運行期檢查) |
參數列表 | 參數列表必須完全一致 | 槽可以忽略信號中多余的參數(信號的參數可以比槽多) |
信號、槽可以是模板 | 信號、槽不能是模板 | |
底層實現 | C++ 直接實現 | 通過由 moc 生成的元對象實現(moc 以及元對象系統都是 C++ 直接實現的) |
內省 | 沒有內省機制 | 可以通過內省發現 可以通過元對象調用 連接可以從資源文件中自動推斷出 |
?都是有疑問的地方。目前還未理解
最重要的是,Qt 的信號槽機制已經深深地植入到框架之中,成為不可分割的一部分。它們可以使用 Qt 專門的開發工具,例如 QtCreator,通過拖拽的方式很輕松的創建、刪除、修改。它們甚至可以通過動態加載資源文件,由特定命名的對象自動動態生成。這些都是 boost 作為一個通用庫所不可能提供的。
-----------------------------------------------------------------------------------------------------------------------------------