在編程中,if-else和switch-case是很常見的分支結構,很少在程序中不用這些控制語句。但是不能否認,在一些場景下,由於分支結構過分長,導致代碼不美觀且不容易維護,在《重構》一書中,也將過長的switch語句當做了“壞味道”。例如當我們處理從網絡接收到的數據時,往往會由於種類太多而寫一長段的if-else或者switch-case,小弟就曾經在讀別人處理網絡數據的代碼時,發現有50多條的if-else語句,導致函數代碼非常長。因此小弟就在網上看各位高人的解決辦法,有很多是支持使用if-else的,也有很多反對的,對於反對的,也有各種的解決方案,例如使用宏屏蔽if-else或者switch代碼,使用函數指針列表等等。小弟在這里只介紹兩種方法,一是使用函數指針列表,二是使用多態。
還希望各位大哥大姐,不惜賜教小弟其他的辦法,多多交流。
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、使用面向對象的多態機制,將實現不同功能的子類繼承父類,然后重載父類的方法,在重載的方法中實現具體的功能。
主函數:
- #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;
}
父類:
- #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:
- #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:
- #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