Boost signal 代码示例

来源:互联网 发布:ios10gamecenter数据 编辑:程序博客网 时间:2024/06/05 08:44

网上介绍Boost signal原理的文章很多,这里不介绍原理,仅贴一些示例代码,这在初步接触Boost signal时能够有个较好的感性认识,深入了解需要去体会挖掘boost源码。代码基本上来自Boost turioal,其中有一些错误会导致编译不过,这里都做了更正:

1. 基本运用

#include <boost/signals2.hpp>#include <boost/bind.hpp>#include <iostream>using namespace std;using namespace boost;struct HelloWorld{  void operator()() const  {    std::cout << "Hello, World!" << std::endl;  }};struct HelloKitty{  void operator()() const  {    std::cout << "Hello, Kitty!" << std::endl;  }};//struct GoodMorning{      void operator()() const      {          std::cout << "... and good morning!" << std::endl;      }};class Hello{    public:        void print()        {            std::cout << "Hello, World!" << std::endl;        }};class World : public boost::signals2::trackable{    public:        void print()        {            std::cout << "Hello, World!" << std::endl;        }};void print_hello(){    std::cout<<"Hello, world"<<std::endl;}void print_sum(float x, float y){      std::cout << "The sum is " << x+y << std::endl;}void print_product(float x, float y){      std::cout << "The product is " << x*y << std::endl;}void print_difference(float x, float y){      std::cout << "The difference is " << x-y << std::endl;}void print_quotient(float x, float y){      std::cout << "The quotient is " << x/y << std::endl;}float product(float x, float y) { return x*y; }float quotient(float x, float y) { return x/y; }float sum(float x, float y) { return x+y; }float difference(float x, float y) { return x-y; }template<typename T>struct maximum{  typedef T result_type;  template<typename InputIterator>  T operator()(InputIterator first, InputIterator last) const  {    // If there are no slots to call, just return the    // default-constructed value    if (first == last)      return T();    T max_value = *first++;    while (first != last) {      if (max_value < *first)        max_value = *first;      ++first;    }    return max_value;  }};template<typename Container>struct aggregate_values{  typedef Container result_type;  template<typename InputIterator>  Container operator()(InputIterator first, InputIterator last) const  {    return Container(first, last);  }};// Signal with no arguments and a void return valueint main(){    // Connect a HelloWorld slot    HelloWorld hello;    HelloKitty kitty;    GoodMorning goodMorning;    std::cout<<"****************sig1******************"<<std::endl;    boost::signals2::signal<void ()> sig1;    sig1.connect(1 ,hello);    sig1.connect(0 ,kitty);    sig1.connect(0 ,goodMorning);    sig1();    // Call all of the slots    std::cout<<"****************sig2******************"<<std::endl;    boost::signals2::signal<void (float, float) > sig2;    sig2.connect(&print_product);    sig2.connect(&print_quotient);    sig2.connect(&print_sum);    sig2.connect(&print_difference);    sig2(5, 3);    std::cout<<"****************sig3*******************"<<std::endl;    boost::signals2::signal<float (float, float) > sig3;    sig3.connect(product);    sig3.connect(quotient);    sig3.connect(sum);    sig3.connect(difference);    std::cout<< *sig3(5,3)<<std::endl;    std::cout<<"****************sig4*******************"<<std::endl;    boost::signals2::signal<float (float, float), maximum<float> > sig4;    sig4.connect(product);    sig4.connect(quotient);    sig4.connect(sum);    sig4.connect(difference);    std::cout<< sig4(5,3)<<std::endl;    std::cout<<"****************sig5*******************"<<std::endl;    boost::signals2::signal<float (float, float), aggregate_values<std::vector<float> > > sig5;    sig5.connect(product);    sig5.connect(quotient);    sig5.connect(sum);    sig5.connect(difference);    std::vector<float> results = sig5(5, 3);    std::copy(results.begin(), results.end(), std::ostream_iterator<float>(cout, "\n"));    std::cout<<"***************connection management connected**************"<<std::endl;    boost::signals2::signal<void ()> sig6;    boost::signals2::connection c = sig6.connect(HelloWorld());    if (c.connected())    {        // c is still connected to the signal        sig6(); // Prints "Hello, World!"    }    c.disconnect(); // Disconnect the HelloWorld object    assert(!c.connected());    sig6(); // Does nothing: there are no connected slots     std::cout<<"***************connection management block**************"<<std::endl;    boost::signals2::signal<void ()> sig7;    boost::signals2::connection c1 = sig7.connect(HelloWorld());    sig7();    {        boost::signals2::shared_connection_block block(c1);        sig7();        std::cout<<"c1 is blocked"<<std::endl;    }    assert(!c1.blocked());    sig7();    std::cout<<"***************connection management scoped**************"<<std::endl;    boost::signals2::signal<void ()> sig8;    {        boost::signals2::scoped_connection c2(sig8.connect(HelloWorld()));        sig8();        std::cout<<"c2 is blocked"<<std::endl;    }    sig8();    std::cout<<"***************connection management connected**************"<<std::endl;    boost::signals2::signal<void ()> sig9;    sig9.connect(print_hello);    sig9();    std::cout<<"Disconnected sig9"<<std::endl;    sig9.disconnect(print_hello);    sig9();    std::cout<<"***************connection management use shared_ptr**************"<<std::endl;    boost::signals2::signal<void ()> sig10;    {        boost::shared_ptr<Hello> w(new Hello());        sig10.connect(boost::bind(&Hello::print, w.get()));    }    std::cout <<"num of slots = "<< sig10.num_slots() << std::endl;    sig10();    std::cout<<"***************connection management use trackable**************"<<std::endl;    boost::signals2::signal<void ()> sig11;    {        boost::shared_ptr<World> w(new World());        sig11.connect(boost::bind(&World::print, w.get()));    }    std::cout <<"num of slots = "<< sig11.num_slots() << std::endl;    sig11();    return 0;}

2.  综合运用

#include <iostream>#include <string>#include <boost/signals2.hpp>#include <boost/bind.hpp>class NewsItem{public:    NewsItem();    NewsItem(const NewsItem& item)    {        msg = item.msg;    }    NewsItem(const std::string message)    {        msg = message;    }    const std::string text() const    {        return msg;    }private:    std::string msg;};class MessageArea{public:    MessageArea(){messageText = "default";}    MessageArea(const MessageArea& messageArea)    {        messageText = messageArea.messageText;    }    MessageArea(const std::string  message)    {        messageText = message;    }    void update()    {        std::cout <<"messageText="<<messageText<<std::endl;    }    std::string messageText;};class NewsMessageArea : public MessageArea, public boost::signals2::trackable//trackable is important{public:    NewsMessageArea(const std::string message):MessageArea(message){}    void displayNews(const NewsItem& news)    {        messageText = news.text();        update();    }};int main(){    boost::signals2::signal<void (const NewsItem&) > deliverNews;    NewsMessageArea* newsMessageArea = new NewsMessageArea("Hello, World!");    deliverNews.connect(boost::bind(&NewsMessageArea::displayNews, newsMessageArea, _1));    const NewsItem newItem("Hello, Kitty!");    deliverNews(newItem);       delete newsMessageArea;    std::cout<<"*******Segmentation fault below if no trackable******"<<std::endl;    deliverNews(newItem);    return 0;}

3. Boost Signal 运用于Documnet-View 模式

#include <iostream>#include <string>#include <boost/signals2.hpp>#include <boost/bind.hpp>class Document{public:    typedef boost::signals2::signal<void (bool)>  signal_t;    typedef boost::signals2::connection  connection_t;public:    Document()    {}    connection_t connect(signal_t::slot_function_type subscriber)    {        return m_sig.connect(subscriber);    }    void disconnect(connection_t subscriber)    {        subscriber.disconnect();    }    void append(const char* s)    {        m_text += s;        m_sig(true);    }    const std::string& getText() const    {        return m_text;    }private:    signal_t    m_sig;    std::string m_text;};class View{public:    View(Document& m)        : m_document(m)    {        m_connection = m_document.connect(boost::bind(&View::refresh, this, _1));    }    virtual ~View()    {        m_document.disconnect(m_connection);    }    virtual void refresh(bool bExtended) const = 0;protected:    Document&               m_document;private:    Document::connection_t  m_connection;};class TextView : public View{public:    TextView(Document& doc)        : View(doc)    {}    virtual void refresh(bool bExtended) const    {        std::cout << "TextView: " << m_document.getText() << std::endl;    }};class HexView : public View{public:    HexView(Document& doc)        : View(doc)    {}    virtual void refresh(bool bExtended) const    {        const std::string&  s = m_document.getText();        std::cout << "HexView:";        for (std::string::const_iterator it = s.begin(); it != s.end(); ++it)            std::cout << ' ' << std::hex << static_cast<int>(*it);        std::cout << std::endl;    }};int main(int argc, char* argv[]){    Document    doc;    TextView    v1(doc);    HexView     v2(doc);    doc.append(argc == 2 ? argv[1] : "Hello world!");    return 0;}

另外这篇文章队Boost Signal的trackable特性有较为深入的分析,推荐大家可以参考下

http://www.cppblog.com/Error/archive/2014/05/30/207147.html

1 0
原创粉丝点击