表驱动是一种非常好的编程技巧,在代码中合理的使用表驱动能够有效的消除掉大片的if else以及switch case语句,并且能够在一定程度商提升代码的性能,因为
表驱动通常是使用了哈希,或者是查找树来做索引,相比较顺序的遍历要快。
这儿,给出一种在C++类中使用表驱动编程方法的例子。
假设你当前在实现一个不同协议的消息包处理工具,能够处理不同网络协议的消息包,TCP,UDP,SCTP等。
enum MsgType
{
PROTO_TCP,
PROTO_UDP,
PROTO_SCTP,
PROTO_NULL,
};
class Msg
{
public:
int type;
int size;
};
class MsgProc
{
public:
MsgProc();
~MsgProc();
int Proc(enum MsgType t, Msg* m);
private:
int TcpProc(Msg* m);
int UdpProc(Msg* m);
int SctpProc(Msg* m);
int ProcError(Msg* m);
private:
typedef int (MsgProc::*proc)(Msg* m);
struct tbl
{
enum MsgType msg_type;
proc msg_proc;
};
static struct tbl m_proc[];
};
这儿使用了静态可变数组来存储表格,当然也可以使用map或者是其他的数据结构来实现。但是静态数组其实就是最简单的了(在索引量不多,并且比较简单的情况下)。
然后给出源程序:
#include <iostream>
#include "msgproc.h"
using std::cout;
using std::endl;
struct MsgProc::tbl MsgProc::m_proc[] = {
{PROTO_TCP, &MsgProc::TcpProc},
{PROTO_UDP, &MsgProc::UdpProc},
{PROTO_SCTP, &MsgProc::SctpProc},
{PROTO_NULL, &MsgProc::ProcError},
};
MsgProc::MsgProc()
{
}
MsgProc::~MsgProc()
{
}
int MsgProc::TcpProc(Msg* m)
{
cout << "TcpProc:" << m->type << m->size << endl;
return 0;
}
int MsgProc::UdpProc(Msg* m)
{
cout << "UdpProc:" << m->type << m->size << endl;
return 0;
}
int MsgProc::SctpProc(Msg* m)
{
cout << "SctpProc:" << m->type << m->size << endl;
return 0;
}
int MsgProc::ProcError(Msg* m)
{
cout << "Error:" << endl;
return -1;
}
int MsgProc::Proc(enum MsgType t, Msg* m)
{
return (this->*m_proc[t].msg_proc)(m);
}
这儿需要注意的是C++中对函数取地址的方式与C是不同的,调用表驱动函数的方式也需要注意一下。