当Boost.Function遇到Boost.Bind

本文详细介绍了如何在C++中利用boost库中的boost::function和boost::bind实现命令模式,将业务逻辑与表示层分离,简化代码结构。通过定义抽象基类Command和其派生类PlayCommand、StopCommand、RecordCommand,实现对录音机类Tape的操作,最终通过typedef将多个Command类简化为通用的Command类型,进一步减少代码量。

C语言中的注册回调函数到了C++中有了更好的实现方式,这就是boost::function和boost::bind,bind为普通函数、成员函数提供参数绑定,把他们变成函数对象,而function则可用于保存由bind生成的函数对象。这样就由C中保存函数指针的形式变成C++中保存函数对象的形式,这样对于用户来说不管是传递函数指针或者函数对象都能正确的执行程序,摆脱了C中只能用函数指针的限制。

下面举Beyond the C++ Standard Library: An Introduction to Boost中的一个例子,这个例子实现了把业务逻辑从表示层分离开来。

Tape.h

#ifndef TAPE_H
#define TAPE_H
class Tape{
public:
   void play();
   void stop();
   void record();
};
#endif

Tape.cpp

#include "Tape.h"
#include <iostream>
using namespace std;
void Tape::play(){
   cout<<"play tape\n";
}
void Tape::stop(){
   cout<<"stop tape\n";
}
void Tape::record(){
   cout<<"record tape\n";
}

这是一个录音机类,实现了简单的开关和记录功能,这是类的实现部分,现实应用中我们就需要对录音机发号各种命令,也就是说我们需要各种Command类来操作录音机,而为了录音机的实现和控制部分解藕,则可以使用4人帮介绍的Command模式,这样我们就需要定义一个Command的抽象基类,和一系列派生类,PlayCommand,StopCommand,RecordCommand,也就是说由多小命令就定义多少种派生类。PlayCommand类如下所示:

class PlayCommand:public Command{
   Tape *p_;
public:
   PlayCommand(Tape * p):p_(p){}
   bool enabled()cosnt{
      return true;
   }
   void execute(){
      p_play();
   }
};

测试代码

int main(){
   Tape tape;
   Command *pPlay = new PlayCommand(&tape);
   Command *pStop = new StopCommand(&tape);
   pPlay->execute();
   pStop->execute();
   delete pPlay;
   delete pStop;
}
StopCommadn和RecordCommand实现和PlayCommand只有execute()不同,即分别调用stop(),record(),你会发现3个类都一样,调用的函数参数类型和返回类型都一样,那么就可以把这3个函数再抽象一下,用泛型的形式来表示,这样就是Function的形式了。有了Function这样我们再不用Command及其的派生类了,我们只需要定义一个

typedef boost::function<void ()> Command;

3个函数被抽象成没有返回值,没有参数的Function了。测试函数如下所示:

#include "Tape.h"
//#include "Command.h"
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace boost;
typedef function<void ()> Command;
int main(){
   Tape tape;
   Command play( bind(&Tape::play,&tape ));
   Command stop( bind(&Tape::stop,&tape ));
   play();
   stop();
   Command record( bind(&Tape::record,&tape) );
   record();
}

也就是说Command的一系列类被一句typedef的功能完全替代了,大大减少了代码量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值