在编程中,if-else和switch-case是很常见的分支结构,很少在程序中不用这些控制语句。但是不能否认,在一些场景下,由于分支结构过分长,导致代码不美观且不容易维护,在《重构》一书中,也将过长的switch语句当做了“坏味道”。例如当我们处理从网络接收到的数据时,往往会由于种类太多而写一长段的if-else或者switch-case,小弟就曾经在读别人处理网络数据的代码时,发现有50多条的if-else语句,导致函数代码非常长。因此小弟就在网上看各位高人的解决办法,有很多是支持使用if-else的,也有很多反对的,对于反对的,也有各种的解决方案,例如使用宏屏蔽if-else或者switch代码,使用函数指针列表等等。小弟在这里只介绍两种方法,一是使用函数指针列表,二是使用多态。
        还希望各位大哥大姐,不惜赐教小弟其他的办法,多多交流。

1、函数指针列表,使用一个结构体将函数指针和一个标示指针的字符串封装起来,然后通过匹配相应的字符串,执行相应的函数。
      测试代码:

  1. #include <stdio.h>
    #include <string.h>
    /*four functions for test*/
    void functionA(int a);
    void functionB(int b);
    void functionC(int c);
    void functionD(int d);
    /*get the function by key and run it*/
    void exec(const char* key,int value);
    typedef void (*exceFunction)(int);
    typedef struct mapFunction{
        char* key;
        exceFunction fun;
    }mapFunction;
    mapFunction map[4];
    int main(void)
    {
        map[0].key = "a";
        map[1].key = "b";
        map[2].key = "c";
        map[3].key = "d";
        map[0].fun = &functionA;
        map[1].fun = &functionB;
        map[2].fun = &functionC;
        map[3].fun = &functionD;
        // test with changing the keys
        exec("b",1);
        return 0;
    }
    void exec(const char *key, int value){
        int i=0;
        for(;i<4;i++){
            if(strcmp(key,map[i].key)==0){
                map[i].fun(value);
                break;
            }
        }
    }
    void functionA(int a)
    {
        printf("functionA:%d\n",a+1);
    }
    void functionB(int b)
    {
        printf("functionB:%d\n",b+2);
    }
    void functionC(int c)
    {
        printf("functionC:%d\n",c+3);
    }
    void functionD(int d)
    {
        printf("functionD:%d\n",d+4);
    }

2、使用面向对象的多态机制,将实现不同功能的子类继承父类,然后重载父类的方法,在重载的方法中实现具体的功能。
    主函数:

  1. #include <iostream>
    #include <set>
    #include <vector>
    #include "test.h"
    #include "testa.h"
    #include "testb.h"
    using namespace std;
    std::vector<Test*> testVector;
    void exec(const std::string key)
    {
        size_t i=0;
        for(;i<testVector.size();i++){
            Test* test = testVector.at(i);
            if(test->getKey().compare(key)==0){
                 test->test();
                 break;
            }
        }
        // do something
    }
    int main()
    {
        cout << "Hello World!" << endl;
        testVector.push_back(new TestA("a"));
        testVector.push_back(new TestB("b"));
        exec("b");
        return 0;
    }

父类:

  1. #ifndef TEST_H
    #define TEST_H
    #include <string>
    #include <iostream>
    class Test
    {
    public:
        Test(std::string key);
        ~Test();
        const std::string getKey();
        virtual void test(){}
    private:
        std::string key;
    };
    #endif // TEST_H
    #include "test.h"
    Test::Test(std::string key)
    {
        this->key = key;
    }
    Test::~Test()
    {
        this->key = "";
    }
    const std::string Test::getKey()
    {
        return this->key;
    }

子类A:

  1. #ifndef TESTA_H
    #define TESTA_H
    #include <string.h>
    #include <iostream>
    #include "test.h"
    class TestA : public Test
    {
    public:
        TestA(std::string key);
        void test();
    };
    #endif // TESTA_H
    #include "testa.h"
    TestA::TestA(std::string key):Test(key){}
    void TestA::test(){
        std::cout<<"TestA::test()";
    }

子类B:

  1. #ifndef TESTB_H
    #define TESTB_H
    #include <string>
    #include <iostream>
    #include "test.h"
    class TestB : public Test
    {
    public:
        TestB(std::string key);
        void test();
    };
    #endif // TESTB_H

    #include "testb.h"
    TestB::TestB(std::string key):Test(key){}
    void TestB::test()
    {
        std::cout<<"TestB::test()";
    }

小弟才疏学浅,还请各位大神多多指教。

http://www.qtcn.org/bbs/apps.php?q=diary&a=detail&did=2030&uid=163485

使用函数指针和多态代替冗长的if-else或者switch-case的更多相关文章

  1. 2014 0416 word清楚项目黑点 输入矩阵 普通继承和虚继承 函数指针实现多态 强弱类型语言

    1.word 如何清除项目黑点 选中文字区域,选择开始->样式->全部清除 2.公式编辑器输入矩阵 先输入方括号,接着选择格式->中间对齐,然后点下面红色框里的东西,组后输入数据   ...

  2. 关于函数指针与c++多态

    原文  https://www.cnblogs.com/zhchngzng/p/4013031.html 虚函数是实现多态的重要元素,请看: class A { public: void a0(){c ...

  3. C 语言实现多态的原理:函数指针

    C语言实现多态的原理:函数指针 何为函数指针?答案:C Programming Language. 能够查阅下,从原理上来讲,就是一个内存地址.跳过去运行相应的代码段. 既然如此,在运行时决定跳到哪个 ...

  4. C++ 类的多态三(多态的原理--虚函数指针--子类虚函数指针初始化)

    //多态的原理--虚函数指针--子类虚函数指针初始化 #include<iostream> using namespace std; /* 多态的实现原理(有自己猜想部分) 基础知识: 类 ...

  5. 使用函数指针模拟C++多态

    #include <iostream> using namespace std; class Base { public : void display() { cout << ...

  6. typedef 函数指针 数组 std::function

    1.整型指针 typedef int* PINT;或typedef int *PINT; 2.结构体 typedef struct { double data;}DATA,  *PDATA;  //D ...

  7. [Reprint]C++普通函数指针与成员函数指针实例解析

    这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下   C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般 ...

  8. 类成员函数指针 ->*语法剖析

    在cocos2d-x中,经常会出现这样的调用,如 ->*,这个是什么意思呢,如下面得这个例子: , 其实这是对类的成员函数指针的调用,在cocos2dx中,这种形式多用于回调函数的调用.如我们经 ...

  9. C++中怎么获取类的成员函数的函数指针?

    用一个实际代码来说明. class A { public: staticvoid staticmember(){cout<<"static"<<endl;} ...

随机推荐

  1. Android 程式开发:(廿一)消息传递 —— 21.3 使用Intent发送短信

    使用SmsManager类,可以在自己编写的程序内部发送短信,而不需要调用系统的短信应用. 然而,有的时候调用系统内置的短信应用会更加方便. 这时,需要使用一个MIME类型为vnd.android-d ...

  2. HNCU1741:算法3-2:行编辑程序

    http://hncu.acmclub.com/index.php?app=problem_title&id=111&problem_id=1741 题目描述 一个简单的行编辑程序的功 ...

  3. IIS - HTTP 错误 500.21 - Internal Server Error 处理程序“WebServiceHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”

    http://www.cnblogs.com/yc-755909659/p/3445278.html 首先观察,aspnet_regiis.exe文件是不是损坏的,如果是,重新下载,覆盖即可,在百度云 ...

  4. Delphi高仿Windows扫雷游戏(全部都是贴图绘制)

    http://www.newxing.com/Code/Delphi/game/543.html http://www.newxing.com/Code/Delphi/Network/1324.htm ...

  5. 配置nexus仓库

    Nexus有许多默认仓库:Central,Releases,Snapshots,和3rd Party 1.配置central仓库 Nexus内置了Maven中央代理仓库Central.选择仓库列表中的 ...

  6. django-cookieless 0.7 : Python Package Index

    django-cookieless 0.7 : Python Package Index django-cookieless 0.7 Download django-cookieless-0.7.ta ...

  7. Java byte数据类型详解

    public static String bytes2HexString(byte[] b) { String ret = ""; for (int i = 0; i < b ...

  8. ASP.NET - URL中参数加密解密操作

    效果: 代码: using System; using System.Text; using System.IO; using System.Security.Cryptography; public ...

  9. Qt的setMouseTracking使用

    bool mouseTracking 这个属性保存的是窗口部件跟踪鼠标是否生效. 如果鼠标跟踪失效(默认),当鼠标被移动的时候只有在至少一个鼠标按键被按下时,这个窗口部件才会接收鼠标移动事件. 如果鼠 ...

  10. ubuntu 10.04安装qtcreator并汉化

    最近最的项目中需要做出来一个带有界面的demo,所以想到了用qt做个简单的demo! 于是在ubuntu上安装了qt,很简单apt-get apt-get install qtcreator 大概几百 ...