## Signals
### 頭文件: `"boost/signals.hpp"`
通過單個頭文件包含了整個庫。
```
"boost/signals/signal.hpp"
```
包含了 `signal` 的定義。
```
"boost/signals/slot.hpp"
```
包含了 `slot` 類的定義。
```
"boost/signals/connection.hpp"
```
包含了類 `connection` 和 `scoped_connection` 的定義。
要使用這個庫,可以包含頭文件 `"boost/signals.hpp"`,這樣可以確保整個庫可用,或者可以按照你的需要包含單獨的頭文件。Boost.Signals 庫的核心部分定義在名字空間 `boost` 中,高級特性則定義在 `boost::signals` 中。
以下是 `signal` 的部分內容,其后將對其中最主要的成員函數進行了簡要的介紹。如果你需要完整的參考,請見 Signals 的在線文檔。
```
namespace boost {
template<typename Signature,
// Function type R(T1, T2, ..., TN)
typename Combiner = last_value<R>,
typename Group = int,
typename GroupCompare = std::less<Group>,
typename SlotFunction = function<Signature> >
class signal : public signals::trackable,
private noncopyable {
public:
signal(const Combiner&=Combiner(),
const GroupCompare&=GroupCompare());
~signal();
signals::connection connect(const slot_type&);
signals::connection connect(
const Group&,
const slot_type&);
void disconnect(const Group&);
std::size_t num_slots() const;
result_type operator()
(T1, T2, ..., TN);
};
}
```
### 類型
我們先來看看 `signal` 的模板參數。除了第一個參數,其它參數都有相應的缺省值,這有助于理解這些參數的基本意思。第一個模板參數是被調用的函數的簽名。在這種 `signal`s 的情況下,`signal` 本身就是被調用的實體。聲明這個簽名時,使用與普通函數簽名相同的語法\[1\]。例如,一個返回 `double` 且接受一個類型 `int` 的參數的函數簽名應該象這樣:
> \[1\] 細心的讀者可以已經注意到 `boost::function` 也是這樣用的。
```
signal<double(int)>
```
`Combiner` 參數表示一個函數對象,它負責逐個對該 `signal` 所有已連接的插槽(slot)進行調用。它同時也決定如何將組合這些調用返回的結果。缺省的類型是 `last_value`, 它只是簡單地返回最后一個插槽的調用結果。
`Groups` 參數是用于組合所有連接到 `signal` 的插槽的一種類型。通過連接到不同的插槽組,你可以預設調用插槽的順序,同時也可以斷開插槽組。
`GroupCompare` 參數決定了如何排序 `Groups`,缺省值為 `std::less<Group>`, 通常它都是正確的。如果 `Groups` 使用了定制的類型,就有可能需要其它的排序方法。
最后,`SlotFunction` 參數表示插槽函數的類型,缺省值為 `boost::function`. 我想不出有什么理由改變這個缺省值。這個模板參數用于定義插槽的類型,定義的方法是一個公有的 `typedef slot<SlotFunction> slot_type`.
### 成員函數
```
signal(const Combiner&=Combiner(),
const GroupCompare&=GroupCompare());
```
在構造一個 `signal` 時,可以傳入一個 `Combiner`,它是一個負責在信號到達時調用相應插槽并對返回值進行處理的對象。
```
~signal();
```
析構函數在析構時斷開所有已連接的插槽。
```
signals::connection connect(const slot_type& s);
```
`connect` 函數把插槽 `s` 連接到 `signal`. 函數指針、函數對象、`bind` 表達式或者 lambda 表達式都可以用作插槽。`connect` 返回一個 `signals::connection`, 它是代表被創建的連接的句柄。通過使用這個句柄,插槽可以從 `signal` 斷開,或者你也可以測試該插槽是否還有連接。
```
signals::connection connect(const Group& g, const slot_type& s);
```
這個 `connect` 的重載版本與前一個作用相似,但是它還把插槽 `s` 連接到組 `g`. 把一個插槽連接到一個組意味著當一個 `signal` 產生時,屬于較前面的組的插槽會先被調用(即按組的順序來調用,`signal` 模板的 `GroupCompare` 參數定義了組的順序),而且屬于組的所有插槽會在不屬于組的插槽之前被調用(可能只有部分插槽是在組中的)。
```
void disconnect(const Group& g);
```
斷開所有屬于組 `g` 的已連接插槽。
```
std::size_t num_slots() const;
```
返回當前連接到 `signal` 的插槽數量。要測試插槽是否為空,應該調用函數 `empty`,而不要調用 `num_slots` 并測試其返回是否為0,因為 `empty` 的效率更高。
```
result_type operator()(T1, T2, ..., TN);
```
`signal`s 使用調用操作符來調用。當信號產生時,必須傳遞適當的參數給調用操作符,必須符合 `signal` 的簽名(即聲明 `signal` 類型時的第一個模板參數)。參數的類型必須可以隱式轉換為信號所需的類型,只有這樣調用才可以成功。
Boost.Signals 中還有其它的類型,我們將在本章剩余部分討論它們。我們還將討論 `signal` 類中有用的 `typedef`s。
- 序
- 前言
- Acknowledgments
- 關于作者
- 本書的組織結構
- Boost的介紹
- 字符串及文本處理
- 數 據結構, 容器, 迭代器, 和算法
- 函數對象及高級編程
- 泛 型編程與模板元編程
- 數學及數字處理
- 輸入/輸出
- 雜項
- Part I: 通用庫
- Library 1. Smart_ptr
- Smart_ptr庫如何改進你的程序?
- 何時我們需要智能指針?
- Smart_ptr如何適應標準庫?
- scoped_ptr
- scoped_array
- shared_ptr
- shared_array
- intrusive_ptr
- weak_ptr
- Smart_ptr總結
- Library 2. Conversion
- Conversion 庫如何改進你的程序?
- polymorphic_cast
- polymorphic_downcast
- numeric_cast
- lexical_cast
- Conversion 總結
- Library 3. Utility
- Utility 庫如何改進你的程序?
- BOOST_STATIC_ASSERT
- checked_delete
- noncopyable
- addressof
- enable_if
- Utility 總結
- Library 4. Operators
- Operators庫如何改進你的程序?
- Operators
- 用法
- Operators 總結
- Library 5. Regex
- Regex庫如何改進你的程序?
- Regex 如何適用于標準庫?
- Regex
- 用法
- Regex 總結
- Part II: 容器及數據結構
- Library 6. Any
- Any 庫如何改進你的程序?
- Any 如何適用于標準庫?
- Any
- 用法
- Any 總結
- Library 7. Variant
- Variant 庫如何改進你的程序?
- Variant 如何適用于標準庫?
- Variant
- 用法
- Variant 總結
- Library 8. Tuple
- Tuple 庫如何改進你的程序?
- Tuple 庫如何適用于標準庫?
- Tuple
- 用法
- Tuple 總結
- Part III: 函數對象與高級編程
- Library 9. Bind
- Bind 庫如何改進你的程序?
- Bind 如何適用于標準庫?
- Bind
- 用法
- Bind 總結
- Library 10. Lambda
- Lambda 庫如何改進你的程序?
- Lambda 如何適用于標準庫?
- Lambda
- 用法
- Lambda 總結
- Library 11. Function
- Function 庫如何改進你的程序?
- Function 如何適用于標準庫?
- Function
- 用 法
- Function 總結
- Library 12. Signals
- Signals 庫如何改進你的程序?
- Signals 如何適用于標準庫?
- Signals
- 用法
- Signals 總結