c – 如何重构此结构,if-else-if-else-if * 100

前端之家收集整理的这篇文章主要介绍了c – 如何重构此结构,if-else-if-else-if * 100前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有一些令人讨厌的遗留代码.
std::string xxx = GetCommand(); // get "CommandX";
if (xxx == "Command1")
{
    return new Command1();
}
else if (xxx == "Command2")
{
    return new Command2();
}
...
else if (xxx == "Command100")
{
    return new Command100();
}

我想改进这个代码结构.
有太多的比较.所以我把它们放到地图上.

for (int i = 0; i < GetCommandCount(); ++i)
{
    // key is a command string
    // value is a function pointer which creates it's instance
    map.insert(command,a function pointer);
}

// then

ICommand* pCommand = map.getInstance(command);

但是,如果新的命令来了,这种方式必须每次增加一些功能.
是的,这些功能可能是合理的.但是所有的功能只是返回新的CommandNNN();我想有办法删除重复.

你怎么想?

解决方法

由于所有函数都返回新的CommandNNN();可以使用模板函数
template <class T>
CommandBase* createCommand() {
    return new T();
}

并绑定到您的地图中的此功能

map.insert(std::make_pair("Command1",&createCommand<Command1>));
map.insert(std::make_pair("Command2",&createCommand<Command2>));
map.insert(std::make_pair("Command3",&createCommand<Command3>));

这样可以避免为每个命令创建一个新功能.但是,map.insert-statements中仍然会有一些重复.这可以通过使用宏进一步减少,如果这是你的一杯茶:

#define INSERT(cmd) map.insert(std::make_pair(#cmd,&createCommand<cmd>));

INSERT(Command1);
INSERT(Command2);
INSERT(Command3);

#undef INSERT

要么

#define INSERT(n) map.insert(std::make_pair("Command" #n,&createCommand<Command ## n>));

INSERT(1);
INSERT(2);
INSERT(3);

#undef INSERT

我怀疑你甚至可以让预处理器为你做一些计数,但这不在我的域之外.

应用更多的宏,以及一些全球国家,这两个都被许多人所皱眉,你可以获得更加紧密的耦合:

#include <map>
#include <string>
#include <cassert>

class CommandBase {};

static std::map<std::string,CommandBase* (*)()> g_commandMap;

template <class C>
CommandBase* createCommand() {
    return new C();
}

class CommandRegistrer {
public:
    CommandRegistrer(const std::string& name,CommandBase* (*instantiator)()) {
        g_commandMap.insert(std::make_pair(name,instantiator));
    }
};

#define COMMAND_CLASS(n) \
    class Command##n; \
    CommandRegistrer g_commandRegistrer##n("Command" #n,createCommand<Command##n>); \
    class Command##n : public CommandBase

COMMAND_CLASS(1) { /* implementation here */ };
COMMAND_CLASS(2) { /* implementation here */ };

int main() {
    assert(g_commandMap.find("Command1") != g_commandMap.end());
}

猜你在找的C&C++相关文章