Sigslot學習筆記

最近在學習Sigslot輕量級的庫。看了一些網上的很多牛人博客資料,總結了一下:

1.sigslot簡介

  sigslot是一個線程安全、類型安全,用C++實現的sig/slot機制(sig/slot機制就是對象之間發送和接收消息的機制)的開源代碼庫。是一個非常好用的庫,只有一個頭文件sigslot.h

2.sigslot優點
1.不用擔心空回調,當回調對象析構時會自動disconnect
2.支持多線程,線程安全,有鎖
3.sigslot缺點
1.只能回調void類型函數,不支持返回值。//boost中的signals庫架構類似,支持返回值,但引入了boost中的其他庫
2.slot沒有優先級,不能動態調整回調隊列中的先後順序
4.舉個例子
我們設計一個發送消息的類,這個類負責在某種時刻向外界發出求救信號
#include "sigslot.h"
class Sender  
{
public:
    // 定義信號,該信號有兩個參數
    sigslot::signal2< std::string , int > SignalDanger;
    
    // 該函數發送消息
    void Panic()
    {
        SignalDanger("Help!", 0); 
    }
};

另外一個類則負責接收求助信號:
class Receiver : public sigslot::has_slots<>
{
public:
    // 接收SignalDanger 信號的函數,該函數參數必須和信號的參數一致
    void OnDanger(std::string message, int time)
    {
        printf("I heard something like "%s" at %d!n", message.c_str(), time);
    }
};

現在讓我們在主邏輯中把這兩個類連接起來

Sender sender;
Receiver receiver;
// 將發送者的信號連接到接收方的接收函數上;和斷開連接
sender.SignalDanger.connect(&receiver, Receiver::OnDanger);
sender.SignalDanger.disconnect(&receiver);
只要在任何時候調用 sender.Panic()函數,就會把求救信號發送給接收者,而且這兩個發送和接收端的模塊都可以獨立編譯,不會出現版本問題。
5.解析上述代碼:
Sender類中sigslot::signal2< std::string , int > SignalDanger 是 定義SignalDanger信號;//sig/slot可以帶參數也可以不帶,最多可以帶8個參數
Sender類中Panic()函數裏的 SignalDanger("Help!", 0),稱之爲sig,即用來發出信號;
        Receiver類中而繼承has_slots<>的類receiver的成員函數 void OnDanger(std::string message, int time),稱之爲slot,即信號的處理函數。//其參數要與發送信號帶的參數個數類型要一致
sigslot的核心就在這裏,就是通過這兩個建立對應關係來實現對象間的消息交互。
sig是一個成員變量,它形如:signal+n<type1,type2……>//後面的n表示signal可以接收幾個參數,類型任意,最多爲8個。這是由庫中指定的,當然如果實際開發需要更多的參數,可以修改sigslot庫。
slot是一個成員函數,它形如:void SlotFunction(type1,type2……) //需要記住:slot的類必須繼承has_slots<>;成員函數的返回值必須爲void類型,這是這個庫的侷限性,當然如果實際開發需要返回值,也是可以修改sigslot庫來實現。此外還需要注意的是slot的原形需要與sig一致。怎麼說呢,就是signal只能與帶有與它相同參數個數的slot函數進行綁定,而且signal的參數是直接傳遞給slot的
連接信息號:
sender.SignalDanger.connect(&receiver, Receiver::OnDanger);
通過調用sig的connect函數建立sig和slot間的對應關係。Connect函數接收兩個參數,一個是消息目的對象的地址(指針),另一個是目的對象的成員函數指針(slot)。爲了讓整個機制有效運行,目的類必須從has_slots<>繼承,並且sig/slot參數類型必須一致。也可以將一個sig連接到多個slot上,這樣每次sig發出信號的時候,每個連接的slot都能收到該信號。

斷開信號連接:
sender.SignalDanger.disconnect(&receiver);
sender.SignalDanger.disconnect_all();
通過調用sig的disconnect函數斷開sig和slot之間的連接,只有一個參數:目的對象的地址。一般不需要顯式調用disconnect函數,在sig類和目的類(包含slot函數的類)析構函數中將自動調用disconnect斷開sig和slot的連接。也可使用disconnect_all斷開該sig的所有slot。

5.命名規則
信號命名:signal....
收到信號:on...


連接信息號
通過調用sig的connect函數建立sig和slot間的對應關係。Connect函數接收兩個參數,一個是消息目的對象的地址(指針),另一個是目的對象的成員函數指針(slot)。爲了讓整個機制有效運行,目的類必須從has_slots<>繼承,並且sig/slot參數類型必須一致。也可以將一個sig連接到多個slot上,這樣每次sig發出信號的時候,每個連接的slot都能收到該信號。
 
斷開信號連接
通過調用sig的disconnect函數斷開sig和slot之間的連接,只有一個參數:目的對象的地址。一般不需要顯式調用disconnect函數,在sig類和目的類(包含slot函數的類)析構函數中將自動調用disconnect斷開sig和slot的連接。也可使用disconnect_all斷開該sig的所有slot。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章