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

在编程中,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

时间: 2024-11-02 23:32:14

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

C++中用成员函数指针模拟多态

1.成员函数指针的用法 1 #include <iostream> 2 using namespace std; 3 class base 4 { 5 public: 6 int test(int lhs,int rhs) 7 { 8 cout<<"base test"<<endl; 9 return 1; 10 } 11 }; 12 class derived:public base 13 { 14 public: 15 int test(int

结构体中定义函数指针

转自:http://blog.csdn.net/unix21/article/details/9293877 结构体指针变量的定义,定义结构体变量的一般形式如下: 形式1:先定义结构体类型,再定义变量 struct结构体标识符 { 成员变量列表;… }; struct 结构体标识符 *指针变量名; 变量初始化一:struct结构体标识符 变量名={初始化值1,初始化值2,…, 初始化值n }; 形式2:在定义类型的同时定义变量 struct结构体标识符 { 成员变量列表;… } *指针变量名;

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

C语言实现多态的原理:函数指针 何为函数指针?答案:C Programming Language. 可以查阅下,从原理上来讲,就是一个内存地址,跳过去执行对应的代码段. 既然如此,在运行时决定跳到哪个地方去执行特定的代码即可. 一个简单的版本: 以音频解码器作为例子:AAC 解码器,Mpeg解码器,以及其他类型的解码器. 那手动的多态可能会这样实现: U32 audioHandle = AudioDecOpen(int type) { if(type == aac) return aac_ope

C++基础8【难】 回顾:数组指针,函数指针,函数指针做函数参数 C语言多态

1,数组指针语法梳理 回顾,如何定义数组数据类型: 回顾,如何定义指针类型数组: 回顾,如何直接定义 一个指向数组类型的指针: 2,函数指针语法梳理 1)如何定义一个函数类型 2)如何定义一个函数指针类型 3)如何定义一个函数指针(指向一个函数的入口地址) [中级程序员 转 高级程序员的 必经之路] 1,函数类型做函数的参数 把函数的入口地址传过来,奇怪的效果:[多态就是这样] 函数指针 做 函数参数 思想剖析 1,数组指针语法梳理 回顾,如何定义数组数据类型: [email protected

Day8 函数指针做函数参数

课堂笔记 课程回顾 多态 virtual关键字 纯虚函数 virtual func() = 0; 提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. 多继承的二义性 . 重载 重写 重定义. 实现多态的理论基础:函数指针做函数参数. vptr指针与虚函数表. 构造函数不应为虚函数 多态会降低程序的执行速度.不建议所有的函数都是虚函数. 多态时的指针步进. 多继承在项目开发中使用的比较少. linux从2.4内核升级到2.6的时候,做到了电源可以热插拔,提前将电源驱动的接口规划

成员函数指针与高性能的C++委托

成员函数指针与高性能的C++委托(上篇) 撰文:Don Clugston 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做"闭包(closure)"或"委托 (delegate)")在一些语言中已经证明了它宝贵的价值.在Delphi (Object Pascal)中,面向对象的函数指针是Borland可视化组建库(VCL,Visual Component Library)的基础.而在目前,C#使"委托&

函数指针介绍及其用法

1.前言 这里有两个绕来绕去的东西,函数指针和指针函数:对于四个字,我们首先只看后面两个字,这样方便我们记忆: 函数指针,本质是指针:是指向函数入口地址的指针. 指针函数,本质是函数:返回类型为指针的函数. 2.介绍 对于一个函数而言,函数名是指向函数第一条指令的常量指针.在程序编译之后,编译器会为每个函数分配首地址,即该函数第一条指令的地址.一般情况下,我们可以用一个指针来保存这个地址,而这个指针就是函数指针.所以函数指针实际就是指向函数的别名,我们就可以用这个指针来调用这个函数. 3.用途

libsvm代码阅读(2):svm.cpp浅谈和函数指针(转)

svm.cpp浅谈 svm.cpp总共有3159行代码,实现了svm算法的核心功能,里面总共有Cache.Kernel.ONE_CLASS_Q.QMatrix.Solver.Solver_NU.SVC_Q.SVR_Q 8个类(如下图1所示),而它们之间的继承和组合关系如图2.图3所示.在这些类中Cache.Kernel.Solver是核心类,对整个算法起支撑作用.在以后的博文中我们将对这3个核心类做重点注解分析,另外还将对svm.cpp中的svm_train函数做一个注解分析. 图1 图2 图3

55)函数指针和其意义

1) 2)C语言面向接口编程:其实就是  函数指针的灵活应用 C语言精髓  就是  指针和 函数指针(间接使用 变量或者 函数) 3)看我的一个函数指针的妙用: 在main()里面  通过一个形参是 指向   int     (int ,int)这样的 函数指针,实现了  我在一个接口中  调用不同的类似于  int     (int ,int)这种格式的函数进去,从而产生不同的行为操作.  其实,上面的这个就是C++中的多态的实现 原文地址:https://www.cnblogs.com/xi