成员函数指针在开发中的实际应用

成员函数指针在开发中的实际应用

作者:dozb

前几天我的《成员函数指针》一文,主要介绍了类成员函数指针的使用方法,大家看了后认为意义不大,那是因为你可能还没有真正在开发中遇到需要用成员函数指针的情况。这篇文章就作为《成员函数指针》一文补充,举例说明在什么情况下使用成员函数指针来简化开发。

设想我们要实现一个命令解释器类,就是这个类包括了若干个命令,通常我们的实现方法如下:

class CmdProcess
{
public:
     CmdProcess();
    int execCmd(char *cmd,int argc,char*argv[]);
    void getCmdHelp(char *cmd,char* cmdhelp);
private:
    int cmd_login(int argc,char*argv[]);
    int cmd_logout(int argc,char*argv[]);
    int cmd_putfile(int argc,char*argv[]);
    int cmd_getfile(int argc,char*argv[]);
    int cmd_listfile(int argc,char*argv[]);
    int cmd_delfile(int argc,char*argv[]);
};

//根据传入的命令名字和参数执行命令
int CmdProcess::execCmd(char *cmd,int argc,char*argv[])
{
    if(strcmp(cmd,"login")==0)
     return   cmd_login(argc,argv);
    else  if(strcmp(cmd,"logout")==0)
      return cmd_logout(argc,argv);
    else if(strcmp(cmd,"putfile")==0)
      return cmd_putfile(argc,argv);
    else if(strcmp(cmd,"getfile")==0)
     return  cmd_getfile(argc,argv);
    else if(strcmp(cmd,"listfile")==0)
     return  cmd_listfile(argc,argv);
    else if(strcmp(cmd,"delfile")==0)
     return  cmd_delfile(argc,argv);
     return -1;
}

//根据传入的命令名字获取命令的帮助信息
void CmdProcess::getCmdHelp(char *cmd,char* cmdhelp)
{
    if(strcmp(cmd,"login")==0)
       ...
    else  if(strcmp(cmd,"logout")==0)
       ...
    else if(strcmp(cmd,"putfile")==0)
       ...
    else if(strcmp(cmd,"getfile")==0)
       ...
    else if(strcmp(cmd,"listfile")==0)
       ...
    else if(strcmp(cmd,"delfile")==0)
       ...
}

从上面可以看出,命令函数只是函数名不同,而参数和返回值相同,但是每次都要遍历所有的命令,烦不烦?更要命的是要是新增加一个命令,就需要修改所有的函数!假如你忘了修改一个地方,嘿嘿,后果是什么你也猜到了吧。

下面是用函数指针来实现相同的功能,可能看起来复杂一些,但要是遵循这个规则,使用起来还是比较简单的。

class CmdProcess
{
public:
     CmdProcess();
    int execCmd(char *cmd,int argc,char*argv[]);
    void getCmdHelp(char *cmd,char* cmdhelp);
private:
    typedef int (CmdProcess::* CMDFUN)(int argc,char*argv[]);//命令函数格式定义
    #define _CMDCOUNT 6
    struct _CMDINFO
    {
 char szCmdName[10];//命令名称
 char szCmdHelp[100];//命令帮助信息
 CMDFUN cmdFun;    //命令函数
 _CMDINFO(char* szCmdName,char* szCmdHelp,CMDFUN cmdFun)
 {
            strcpy(this->szCmdName,szCmdName);
     strcpy(this->szCmdHelp,szCmdHelp);
     this->cmdFun = cmdFun;
 };
    };
    _CMDINFO cmdInfoList[_CMDCOUNT];
    _CMDINFO * getCmdInfo(char *cmd);
private:
    int cmd_login(int argc,char*argv[]);
    int cmd_logout(int argc,char*argv[]);
    int cmd_putfile(int argc,char*argv[]);
    int cmd_getfile(int argc,char*argv[]);
    int cmd_listfile(int argc,char*argv[]);
    int cmd_delfile(int argc,char*argv[]);
};

//初始化成员函数指针的值
CmdProcess::CmdProcess()
{
    int i=0;
    cmdInfoList[i++] = _CMDINFO("login","login ....",cmd_login);
    cmdInfoList[i++] = _CMDINFO("logout","logout ....",cmd_logout);
    cmdInfoList[i++] = _CMDINFO("putfile","putfile ....",cmd_putfile);
    cmdInfoList[i++] = _CMDINFO("getfile","getfile ....",cmd_getfile);
    cmdInfoList[i++] = _CMDINFO("listfile","listfile ....",cmd_listfile);
    cmdInfoList[i++] = _CMDINFO("delfile","delfile ....",cmd_delfile);
}

//根据命令字找命令
_CMDINFO * CmdProcess::getCmdInfo(char *cmd)
{
   for(int i=0;i<_CMDCOUNT;i++)
   {
 if(strcmp(cmd,cmdInfoList[i].szCmdName)==0)
    return &cmdInfoList[i];
   }
   return NULL;
}

//根据传入的命令字和参数执行命令
int CmdProcess::execCmd(char *cmd,int argc,char*argv[])
{
   _CMDINFO * pCmdInfo = getCmdInfo(cmd);
   if(pCmdInfo)
      return (this->*(pCmdInfo->cmdFun))(argc,argv);//注意如何使用成员函数指针
   return -1;
}

//根据传入的命令字获取命令帮助信息
void CmdProcess::getCmdHelp(char *cmd,char* cmdhelp)
{
   _CMDINFO * pCmdInfo = getCmdInfo(cmd);
   if(pCmdInfo)
      strcpy(cmdhelp,pCmdInfo->szCmdHelp);

}

这种方式,当新增命令时,需要修改命令个数,和把相应命令添加到cmdInfoList就可以了。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值