首页 > 代码库 > Boost signal 代码示例

Boost signal 代码示例

网上介绍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 = http://www.mamicode.com/*first++;>
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

Boost signal 代码示例