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 = *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 value
int 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

时间: 2024-10-22 02:19:53

Boost signal 代码示例的相关文章

Boost::Regex代码示例

看一个别人给出的例子,当我们输入“select 字符串 from 字符串”的时候,会得到输出:如果不符合这个格式,就会输出error.注意:在命令行下输入的时候,按ctrl+Z.回车表示行输入结束. #include <cstdlib> #include <stdlib.h> #include <boost/regex.hpp> #include <string> #include <iostream> using namespace std;

计算DXFReader中多边形的面积代码示例

在DXFReader中, 一般的多边形的面积计算绝对值 其中K表是顶点的数目,它们的坐标,用于在求和和, 所以用下面的代码就可以计算出一个封闭的多段线的区域: view source print? 01 Dim Vertex As Object 02 Dim Entity As Object 03 Dim k As Long 04 Dim i As Long 05 Dim Area As Single 06 07 With DXFReader1 08 09  For Each Entity In

代码示例:一些简单技巧优化JavaScript编译器工作详解,让你写出高性能运行的更快JavaScript代码

告诉你一些简单的技巧来优化JavaScript编译器工作,从而让你的JavaScript代码运行的更快.尤其是在你游戏中发现帧率下降或是当垃圾回收器有大量的工作要完成的时候. 单一同态: 当你定义了一个两个参数的函数,编译器会接受你的定义,如果函数参数的类型.个数或者返回值的类型改变编译器的工作会变得艰难.通常情况下,单一同态的数据结构和个数相同的参数会让你的程序会更好的工作. function example(a, b) { // 期望a,b都为数值类型 console.log(++a * +

jquery操作单选钮代码示例

jquery操作单选钮代码示例:radio单选按钮是最重要的表单元素之一,下面介绍一下常用的几个jquery对radio单选按钮操作.一.取消选中: $(".theclass").each(function(){ if($(this).attr('checked')) { $(this).attr('checked',false); } }); 以上代码可以将class属性值为theclass的被选中单选按钮取消选中.二.获取被选中的单选按钮的值: var val=$('.thecla

Python实现各种排序算法的代码示例总结

Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示例总结,其实Python是非常好的算法入门学习时的配套高级语言,需要的朋友可以参考下 在Python实践中,我们往往遇到排序问题,比如在对搜索结果打分的排序(没有排序就没有Google等搜索引擎的存在),当然,这样的例子数不胜数.<数据结构>也会花大量篇幅讲解排序.之前一段时间,由于需要,我复习了

领域驱动开发推荐代码示例 — Microsoft NLayerApp

简介: Microsoft NLayerApp是由微软西班牙团队出品的基于.NET 4.0的“面向领域N层分布式架构”代码示例,在codeplex上的地址是:http://microsoftnlayerapp.codeplex.com/. 架构图: 点击查看大图 代码下载:http://microsoftnlayerapp.codeplex.com/releases/view/56660 所用到的软件: - Microsoft Visual Studio 2010  - Microsoft Ex

Aspectj快速上手代码示例之Before,After,Around

本文不打算解释AOP的相关专业名词和概念,仅通过几个代码示例来展示Aspectj(对AOP实现的)的基本使用,并且使用的Aspectj是目前最新版本. 1.搭建环境 本文使用Maven来构建工程,通过aspectj-maven-plugin插件来编译*.aj文件至.class. Maven的具体配置: <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin&

jxl创建Excel文件java代码示例

记得要下载 并 导入 jxl.jar 包,免积分下载地址:http://download.csdn.net/detail/u010011052/7561041 package Test; import java.io.*; import jxl.*; import jxl.format.Colour; import jxl.write.*; public class JXLTest { private static WritableWorkbook book; private static Wr

java 翻盖hashCode()深入探讨 代码示例

package org.rui.collection2.hashcode; /** * 覆盖hashcode * 设计HashCode时最重要的因素 就是:无论何时,对同一个对象调用HashCode都应该产生同样的值, * 如果你的HashCode方法依赖于对象中易变的数据,用户就要当心了,因为此数据发生变化 时 * HashCode就会生成一个不同的散列码,相当于产生一个不同的健 * 此外 也不应该使HashCode依赖于具有唯一性的对象信息,尤其是使用this的值,这只能很糟糕, * 因为这