如何在不使用大量if
或switch
语句的情况下根据变量值运行函数?
目前我正在重复大量代码并做这样的事情
2个变量代表我从套接字读取的数据。 我需要根据我收到的数据做一些不同的事情
//Class1.h
class Class1 {
public:
Class1();
virtual ~Class1();
unsigned char mode = 0x00;
unsigned char type = 0x00;
Interface* o;//in this case I’m creating an object not running a function
};
//Class1.cpp
#include "Class1.h"
Class1::Class1(){
switch(mode){
case 0x00:
switch(type){
case 0x00:
o = new Class2();
break;
case 0x01:
o = new Class3();
break;
case 0x02:
o = new Class4();
break;
}
//case 0x03
//case 0x04
//...
break;
//case 0x01
//case 0x02
//...
default:
break;
}
}
答案 0 :(得分:0)
没有真正干净的解决方案,但是如果你真的有名为“Class%d”的类,你可以利用预处理器通过将变量的值作为类名的一部分来缩短代码。
我不太喜欢这个,但我想不出太多的选择。
#define HANDLE_HUNDREDS_OF_CASES(x) case x: o = new Class##x(); break;
int type=1;
switch(type) {
HANDLE_HUNDREDS_OF_CASES(0); //< Will construct a new Class0 if type==0
HANDLE_HUNDREDS_OF_CASES(1); //< Will construct a new Class1 if type==1
HANDLE_HUNDREDS_OF_CASES(2); // Etc ...
HANDLE_HUNDREDS_OF_CASES(5);
HANDLE_HUNDREDS_OF_CASES(100);
default:
break;
}
如果你只想调用函数而不是构造函数,你可以创建一个函数指针数组,并使用你的变量作为该数组的索引。
答案 1 :(得分:0)
为什么不使用向量保存所有类对象,并通过收到的数据获取对象。
class Base{
virtual void doSomeThing();
}
class A : public Base{
virtual void doSomeThing() {
}
}
class B : public Base{
virtual void doSomeThing() {
}
}
class Handler {
vector<Base *> vet;
void init() {
vet.push_back(new A());
vet.push_back(new B());
}
void handle(int code) {
Base * obj = vet.get(code);
obj->doSomeThing();
}
}
答案 2 :(得分:0)
我将实例创建拆分为自己的工厂类,如下所示:
#include <map>
#include <cstdint>
#include <iostream>
class Interface
{
public:
virtual ~Interface() = 0;
};
Interface::~Interface() {}
class InterfaceFactory
{
public:
typedef Interface* (*InterfaceCreator)();
void registerInterface(unsigned char mode , unsigned char type, InterfaceCreator creator )
{
int16_t key = getKey(mode, type);
table[key] = creator;
}
Interface* createInterface(unsigned char mode, unsigned char type) const
{
int16_t key = getKey(mode, type);
Interface* iface = nullptr;
std::map<int16_t, InterfaceCreator>::const_iterator cit = table.find(key);
if (cit != table.end())
iface = (*(cit->second))();
return iface;
}
private:
int16_t getKey(unsigned char mode, unsigned char type) const
{
int16_t key = mode;
key <<= 8;
key += type;
return key;
}
std::map<int16_t, InterfaceCreator> table;
};
//StreamProcessor.h
class StreamProcessor {
public:
StreamProcessor(const InterfaceFactory& fact)
: factory(fact)
{}
virtual ~StreamProcessor();
bool initHandler(unsigned char mode = 0x00, unsigned char type = 0x00);
private:
const InterfaceFactory& factory;
Interface* o;//in this case I’m creating an object not running a function
};
//StreamProcessor.cpp
//#include "StreamProcessor.h"
bool StreamProcessor::initHandler(unsigned char mode , unsigned char type )
{
o = factory.createInterface(mode, type);
return o != 0;
}
class Class2 : public Interface
{
public:
static Interface* create()
{
return new Class2;
}
};
class Class3 : public Interface
{
public:
static Interface* create()
{
return new Class3;
}
};
int main()
{
InterfaceFactory factory;
factory.registerInterface(0x00, 0x00, &Class2::create);
factory.registerInterface(0x00, 0x01, &Class3::create);
StreamProcessor sp(factory);
if (!sp.initHandler(0x00, 0x01))
{
throw "Unknown interface type";
}
return 0;
}