1. 程式人生 > >c++ boost庫--訊號處理

c++ boost庫--訊號處理

c++ boost庫–訊號處理

標籤(空格分隔): c++ boost

概述

在windows程式設計中,每一次按鍵,或者數遍移動,或者其他動作都會向系統訊息佇列中,投遞一條對應的訊息,而應用程式捕捉到對應的訊息後,要在訊息迴圈中做對應的處理,例如按下鍵盤,要會產生WM_KEYDOWN訊息,在訊息迴圈中要對其進行處理。按下按鍵即為事件,而對訊息進行處理的程式碼即為訊息處理器,qt中直接將每一個事件抽象成一個訊號,而事件處理函式封裝成為對應的槽函式。在boost中提供了signal類,來處理上述對應的關係。
本文主要從三個方面介紹boost庫中訊號處理相關知識。
1. 訊號及槽的使用,返回值的獲取
2. 訊號基槽的管理

訊號及槽的應用

訊號的使用分為三步
1. 定義訊號,signal
在signal.hpp signal定義如下

 template<
    typename Signature, // function type R (T1, T2, ..., TN)
    typename Combiner = last_value<typename function_traits<Signature>::result_type>,
    typename Group = int,
    typename GroupCompare = std::less<Group>,
    typename SlotFunction = function
<Signature> > class signal :

模板引數常用的有第一個和第二個,
Signature 函式簽名,即參函式的型別
Combiner 合成器,如果一個訊號連線多個參函式,可以定義一個集合,收集各個函式的返回值

  1. 訊號的管理
    signal提供瞭如下成員方法,用來管理槽函式
disconnect()    //釋放槽函式
num_slots()     //獲取關聯此訊號槽函式的數量
empty()         //連線此訊號的槽函式是否為空
disconnect_all_slots()  //釋放所有連線

同時boost庫提供了boost::signals2::connection來管理槽函式
其成員方法 block unblock分為一用來釋放和啟用槽函式,具體請看下面的用例

用例

#include "stdafx.h"
#include <iostream>
#include <boost/signals2.hpp>
#include <boost/bind.hpp>

using namespace std;
using namespace boost::signals2;

void slots1()
{
    cout<<"slots1 called"<<endl;
}

void slots2()
{
    cout<<"slots2 called"<<endl;
}

class A
{
public:
    static int staticMemberFunc(int param)
    {
        cout<<"A::staticMemberFunc called, param: "<<param<<endl;
        return 0;
    }
    int memberFunc(int param)
    {
        cout<<"A::memberFunc called, param: "<<param<<endl;
        return 0;
    }
};

int main()
{
    boost::signals2::signal<void()> sig;
    boost::signals2::signal<int(int)> sig2;

    A a;
    connection c1 = sig.connect(&slots1);
    connection c2 =sig.connect(&slots2);
    cout<<"First call-------------------"<<endl;
    sig();
    if (c2.connected())
    {
        c2.disconnect();
    }
    cout<<"Second call-------------------"<<endl;
    sig();

    connection c3 =sig2.connect(&A::staticMemberFunc);// 繫結成員函式
    connection c4 =sig2.connect(boost::bind(&A::memberFunc, &a, _1));// 繫結靜態成員函式

    cout<<"Return code is: "<<*sig2(44)<<endl;// 只能返回最後被呼叫的插槽的返回值
    return 0;
}

//Output: 
First call-------------------
slots1 called
slots2 called
Second call-------------------
slots1 called
A::staticMemberFunc called, param: 44
A::memberFunc called, param: 44
Return code is: 0

 注意使用解引用操作符*獲取的只是最後被呼叫的插槽的返回值,如果需要知道每個插槽函式的返回值需要使用合併器(combiner)。示例如下

#include <boost/signal.hpp> 
#include <iostream> 
#include <vector> 
#include <algorithm> 

int func1() 
{ 
  return 1; 
} 

int func2() 
{ 
  return 2; 
} 

template <typename T> 
struct min_element 
{ 
  typedef T result_type; 

  template <typename InputIterator> 
  T operator()(InputIterator first, InputIterator last) const 
  { 
    return T(first, last); 
  } 
}; 

int main() 
{ 
  boost::signal<int (), min_element<std::vector<int> > > s; 
  s.connect(func1); 
  s.connect(func2); 
  std::vector<int> v = s(); 
  std::cout << *std::min_element(v.begin(), v.end()) << std::endl; 
}