假设mf_ptr是类的成员函数指针的 typedef。我们有流动的代码:
map<string, mb_ptr> cmd_table;
cmd_table["exit"] = &class_name::exit;
string cmd;
while (cin >> cmd){
(this->*cmd_table[cmd])();
}
那么我应该如何定义函数 exit() 来退出 while 循环呢?
假设mf_ptr是类的成员函数指针的 typedef。我们有流动的代码:
map<string, mb_ptr> cmd_table;
cmd_table["exit"] = &class_name::exit;
string cmd;
while (cin >> cmd){
(this->*cmd_table[cmd])();
}
那么我应该如何定义函数 exit() 来退出 while 循环呢?
你有几个选择:
在退出函数中引发异常,并在 while 循环中捕获它。
让所有函数返回一个布尔值,无论是否退出 while 循环。
你可以这样做:
while (cin >> cmd && !class_name::exitLoop){
(this->*cmd_table[cmd])();
}
Whereclass_name::exitLoop
将由class_name::exit()
.
我个人会选择:
while(cin >> cmd && cmd != "exit") {
(this->*cmd_table[cmd])();
}
您可以使用(如上指定的方式):
class_name::exit(void) { cin.setstate(eofbit); ... }
...
while(cin >> cmd)
(this->*cmd_table[cmd])();
在这种情况下,循环将在处理完命令后终止exit
(下一轮迭代>>
将失败)。
如果您想获得更大的复杂性,您可以创建一个自定义流提取运算符,
friend istream & operator>>(istream & is, class_name::CmdExecutorClass &comm)
{
string cmd;
cin >> cmd;
if (cmd == "exit")
cin.setstate(eofbit);
else
(comm.table[cmd])();
return is;
}
我可以看到的好处是你可以简单地写:
while (cin >> cmd);
并且您可以处理错误/未知命令(例如,如果键不存在元素,则std::map<...>::operator[]
添加到地图中 - 这可能不是您想要的)。
但是您还需要相当多的胶水来创建类(构造函数或模板以从嵌入的“主”类CmdExecutor
传递引用,...)。table[]
对于一个简单的案例,矫枉过正。
编辑:还应该添加关闭 cin
(这就是设置eof
位的作用,有效地)也可能是不需要的。该fail
位(之后可以再次清除)可能是一个更好的选择。