用bind来解耦

#include "stdafx.h"

#define BOOST_AUTO_TEST_MAIN
#include
#include

#include
#include
#include

#include
using namespace std;

//声明一个函数指针的类型
typedef void (* ON_SEGMENT) (char * );

//用function<> 和指针回调指针来解除耦合
//注意解耦效果: CReader 和 CSaver 没有任何关系
class CReader
{

public:
CReader()
{
m_pFunc=NULL;
m_functor=NULL;

};

void UseFreeFunc(ON_SEGMENT pFunc)
{
m_pFunc=pFunc;
};

void UseFunctor(boost::function functor)
{
m_functor= functor;
};

void Read(char * pchar)
{

if(m_pFunc)
{
m_pFunc(pchar);
};

if(m_functor)
{
m_functor(pchar);
};

}
private:
ON_SEGMENT m_pFunc;//函数指针
boost::function m_functor; //函数对象
};

class CSaver
{
public:
//接受输入的字符,保存在内部变量m_str
void Input(char * pchar)
{
m_str.append(pchar);

};
string m_str;
};

BOOST_AUTO_TEST_CASE(test_bind)
{
//两个类并不知道对方的任何细节
CSaver saver;
CReader reader;

//预先 把函数 CSaver::Input 和要操作的数据 &saver 注册到 reader
//只要函数形式符合(返回值是void,传入参数是char *),都可以注册
//解除CSaver 和 CReader的耦合

//bind产生的函数对象,重载操作符()
//函数对象的本质是 函数指针加this指针,即 操作和数据
//函数对象 比 函数指针优越的地方是可以带有内部状态

reader.UseFunctor( boost::bind(&CSaver::Input, &saver, _1) );

//延时调用,解除CSaver 和 CReader的耦合
//把字符从reader 放入 saver里面
reader.Read("Hello");

reader.Read("Mafeitao");

BOOST_CHECK(saver.m_str=="HelloMafeitao");

}

//asio 里面的 async_accept 的简化版本

//可以接受 函数指针; 比如 async_accept(FreeFunc,Para)

//可以接受 函数对象; 比如
// CSaverFunctor func;
//async_accept(func,Para)

//可以接受 bind
template
void async_accept(AcceptHandler handler, Para p)
{
handler(p);
};

// 自由函数,没有内部状态
void FreeFunc(char * pChar)
{
printf("In FreeFunc %s\n", pChar);
}

BOOST_AUTO_TEST_CASE(bind_asio)
{

//类 CSaver 和 模板函数 async_accept,没有任何关系
CSaver saver;

char *pchar="Hello";

//bind生成一个临时的functor类 CSaverTemp
//类似于
/*
class CSaverTemp
{
public:
void operator ()(char * pchar)
{
m_str.append(pchar);

};
string m_str
}

CSaverTemp saver;

async_accept(saver,pchar);
}
*/

//全局函数 async_accept,接受一个bind产生的函数对象( 函数指针和this指针)
async_accept( boost::bind(&CSaver::Input, &saver,_1) , pchar);

BOOST_CHECK(saver.m_str=="Hello");

pchar="Mafeitao";

async_accept( boost::bind(&CSaver::Input, &saver,_1) , pchar);

BOOST_CHECK(saver.m_str=="HelloMafeitao");

//接受 全局函数指针,和下面的效果一样
async_accept( boost::bind(FreeFunc,_1), pchar);

//接受 全局函数指针,和上面的效果一样
async_accept( FreeFunc, pchar);

}

//带有模板函数的类
class TReader
{
public:

//模板函数
template
void Read(OnReadHandler & handler, Para p)
{
//可以接受 函数指针,参数
//可以接受 函数对象,参数
//可以接受 bind
handler(p);
};

};

BOOST_AUTO_TEST_CASE(bind_template)
{
TReader reader;
CSaver saver;

char *pchar="Hello";

reader.Read(boost::bind(&CSaver::Input, &saver,_1) , pchar);

BOOST_CHECK(saver.m_str=="Hello");

pchar="Mafeitao";

reader.Read( boost::bind(&CSaver::Input, &saver,_1) , pchar);

BOOST_CHECK(saver.m_str=="HelloMafeitao");
}

//函数对象,重载操作符()
//函数对象的本质是 函数指针加this指针,即 操作和数据
//函数对象 比 函数指针优越的地方是可以带有内部状态
class CSaverFunctor
{
public:
void operator ()(char * pchar)
{
m_str.append(pchar);

};
string m_str;
};

BOOST_AUTO_TEST_CASE(test_functor)
{
//带有模板函数的类
TReader reader;

//函数对象
CSaverFunctor saver;

//把字符从reader 放入 saver里面
char *pchar="Hello";
reader.Read( saver , pchar);

pchar="Mafeitao";
reader.Read( saver , pchar);

BOOST_CHECK(saver.m_str=="HelloMafeitao");

}

2 Comments »

  1. 金庆 said,

    September 3, 2008 @ 14:30

    gcc 编译报错,不知为什么?
    TReader::Read(OnReadHandler & handler, Para p)
    改为TReader::Read(OnReadHandler handler, Para p)才行,
    但行为就变了,handler无法保存状态了。

    D:\Temp\Bind\main.cpp||In member function `void bind_template::test_method()':|
    D:\Temp\Bind\main.cpp|167|error: no matching function for call to `TReader::Read(boost::_bi::bind_t, boost::_bi::list2, boost::arg (*)()> >, char*&)'|
    D:\Temp\Bind\main.cpp|153|note: candidates are: void TReader::Read(OnReadHandler&, Para&) [with OnReadHandler = boost::_bi::bind_t, boost::_bi::list2, boost::arg (*)()> >, Para = char*]|
    D:\Temp\Bind\main.cpp|171|error: no matching function for call to `TReader::Read(boost::_bi::bind_t, boost::_bi::list2, boost::arg (*)()> >, char*&)'|
    D:\Temp\Bind\main.cpp|153|note: candidates are: void TReader::Read(OnReadHandler&, Para&) [with OnReadHandler = boost::_bi::bind_t, boost::_bi::list2, boost::arg (*)()> >, Para = char*]|
    ||=== Build finished: 2 errors, 0 warnings ===|

  2. 金庆 said,

    September 12, 2008 @ 10:09

    reader.Read(boost::bind(&CSaver::Input, &saver,_1) , pchar);
    中boost::bind产生了一个临时对象,但该临时对象无法作为引用传入模板函数

    template
    void Read(OnReadHandler & handler, Para p)

    VC能成功编译吗?应该是不行吧?

RSS feed for comments on this post

发表评论


0.107 sec