我的崇高任务是摆脱单身人士和静态阶级。
背景:
我有以下结构:
问题:
问题是我试图摆脱所有静态类(我现在变成单例进行测试),并且我使系统完全模块化并且松散耦合。这反过来又阻止我进行Cmds可能指向的静态调用。
第一直觉是将函数从typedef更改为模板类,这将存储一个对象和方法,但它看起来非常混乱和复杂,我个人不舒服:
Cmd::create("toggleconsole", Console::toggle);
要:
Cmd::create("toggleconsole", new FunctorObject<Console>(&Console::get(), &Console::toggle));
最终的Cmd创建看起来非常模糊和误导谁负责Functor解除分配。
我也正在将Cmd创建从静态方法调用移动到Commander类中,因此它看起来像 commander.createCmd(“command_name”,...); Cmd :: create(“command_name”,...); 这是因为Commander不再是静态(或单例),因此它处理的所有命令都必须属于它。 / p> 但是,我完全不知道我的选项/替代方案是注册Cmds,并通过允许向Commander发出字符串命令来维持松耦合。
我考虑过让每个主类派生自一个CmdListener类,它会在创建时用Commander注册该对象,然后在执行过程中将命令传递给所有注册的对象,这些对象覆盖了“onCmd”(const Cmd&amp;命令)”。
这也留下了一些未解决的问题:Cmd将如何调用应该调用哪个类的方法?保持指针是没有意义的,并且会受到高度默默无闻的影响(如上所示)。另外,我希望不要在可能处理该cmd的每个类中重新解释onCmd方法中的字符串。
这是一个很多信息,但有没有人对如何处理这个问题有任何想法?
此外,我的所有类都必须知道Commander和Console对象,它们不再是单例/静态。到目前为止,我已将它们放在Context对象中,并将它像一个小胶囊一样传递。关于如何解决这些后单例残留问题的任何想法?
这个项目是我个人的工作,我打算在我的简历上使用它 - 因此,我不希望我的潜在雇主看到任何单身人士(我也不想解释为什么,因为我可以证明他自己并不是真正必要的。)
非常感谢!
编辑:排版。
答案 0 :(得分:5)
这是function
课程的工作。你可以在Boost中找到一个,或者在TR1或C ++ 0x中找到一个。例如,它看起来像std::function<void()>
。这通常与bind
合作,如果您希望以通用方式将引用到功能对象,而不是按值获取它们,您将需要它,并且也可以在Boost,TR1中找到它或C ++ 0x。如果你有lambda函数,你也可以使用它们,这是一种很好的方法。
class Commander {
std::map<std::string, std::function<void()>> commands;
public:
void RegisterCommand(std::string name, std::function<void()> cmd) {
commands[name] = cmd;
}
void CallCommand(std::string name) {
commands[name]();
}
};
void sampleFunc() {
std::cout << "sampleFunc()" << std::endl;
}
struct sampleStruct {
int i;
void operator()() {
std::cout << i;
std::cout << "sampleStruct()() and the value of i is " << i << std::endl;
}
};
int main() {
Commander c;
c.RegisterCommand("sampleFunc", sampleFunc);
sampleStruct instance;
instance.i = 5;
c.RegisterCommand("sampleStruct", instance);
std::string command;
while(std::cin >> command && command != "exit") {
c.CallCommand(command);
}
std::cin.get();
}