如何根据变量的值运行不同的函数?

时间:2015-01-08 01:27:59

标签: c++ function variables

如何在不使用大量ifswitch语句的情况下根据变量值运行函数?

目前我正在重复大量代码并做这样的事情

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;
    }

}

3 个答案:

答案 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;
}