我曾经被告知过的一切都是邪恶的,远离他们,但我认为他们可以帮助我(?)。我想为用户提供一个选项,以便在发现异常时重新启动应用程序,并且在我的工作中遇到一些麻烦......
我的应用程序将由另一个进程监视,但有一些例外,我希望用户能够在不将控制返回给调用进程的情况下决定该做什么。
这样的东西“可以接受”吗?还有其他建议吗?
非常感谢!
int main(){
initialize:
try{
//do things
}
catch(...)
{
cout<<"Would you like to try initializing again?"<<endl;
//if yes
goto initialize;
//if not
abort(); //or something...
}
return 0;
}
答案 0 :(得分:8)
为什么不喜欢这个?
while(true){
//Do stuff
if(exit){
break;
}
}
或
continue = true;
do{
//Do stuff
if(exit){
continue = false;
}
}while(continue);
答案 1 :(得分:6)
int main()
{
while(true)
{
try
{
program();
}
catch(std::exception& e)
{
std::cout << "Start again?" << std::endl;
//Check ...
if(!go_on)
break;
}
}
return 0;
}
答案 2 :(得分:5)
goto
顺便说一句,break
之外的switch
也是如此。 continue
关键字稍微不受谴责,因为至少它会尊重封闭循环的条件。
在正确的地方捕捉异常非常重要 - 您可以最有效地处理这种情况。
如果一个条件变得不方便(就像我的情况中的“再试一次?”),考虑否定它(“失败?”)以获得更清洁的结构。
// Tries until successful, or user interaction demands failure.
bool initialize() {
for ( ;; ) {
try {
// init code
return true;
}
catch ( ... ) {
cout << "Init Failed. Fail Program?" << endl;
if ( yes ) {
return false;
}
}
}
}
int main() {
if ( ! initialize() ) {
return EXIT_FAILURE;
}
// rest of program
return EXIT_SUCCESS;
}
注意:这不使用goto
或break
,并且不会递归(尤其不在{{1}内})。
答案 3 :(得分:4)
是的,从技术上讲它是可以的,但通常会“考虑有害”的考虑因素。
答案 4 :(得分:2)
最初的引用是(我相信)“不受控制地使用goto被视为有害”。 Gotos可能很有用,但必须以受控方式使用。有一种编程技术,用于创建依赖于程序或数据状态的可重入子程序,这些子程序肯定需要定向跳转。虽然这种技术可能被认为是老式的,但我知道它仍然被使用,但是被更现代的语言和编译器功能所隐藏。控制的关键在于你必须停下来问问自己,不仅仅是“是否有一种更有条理的方式来做同样的事情” - @Justin - 而且“在什么具体条件下我会使用goto?”如果没有这个更广泛的答案,方便可能不是使用它的充分条件。
答案 5 :(得分:1)
处理异常的正常方法是在你可以做某事的地方。很明显,你试图处理它们的地方是不对的,因为你必须使用goto。
所以,像这样:
void mainLoop() // get user settings, process, etc
{
try
{
// 1) get user settings
// 2) process data
// 3) inform of the result
}
catch( const exception_type & e)
{
// inform of the error
}
}
int main()
{
try
{
while(true)
mainLoop();
}
catch(...)
{
std::cout<<"an unknown exception caught... aborting() " << std::endl;
}
}