zoukankan      html  css  js  c++  java
  • 使用函数指针和多态代替冗长的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 ",a+1);
      }
      void functionB(int b)
      {
          printf("functionB:%d ",b+2);
      }
      void functionC(int c)
      {
          printf("functionC:%d ",c+3);
      }
      void functionD(int d)
      {
          printf("functionD:%d ",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

  • 相关阅读:
    一个将配置文件转换成xml的示例程序
    DatagridView控件加CheckBox
    Sql Server Split函数
    SQL语句压缩数据库和Log
    NPOI、OpenXML SDK、OpenOffice SDK 操作Excel
    判断参数对象是否为DBNULL
    软件开发模型
    c# ComboBox禁用鼠标滚轮
    动态管理视图和函数的使用
    TreeView 在失去焦点的时候 选中的TreeNode仍为高亮
  • 原文地址:https://www.cnblogs.com/findumars/p/5300417.html
Copyright © 2011-2022 走看看