C++中的错误处理-试图返回到指定的语句

Error handling in C++ - Trying to go back to a specified statement

本文关键字:返回 语句 错误 处理 C++      更新时间:2023-10-16

我在想,有没有什么方法可以在不关闭程序的情况下使用throw/try/catch?

例如:

function
{
restore point:
//code goes here
try "something";
goto restore point;
}

是否有任何方法可以调用函数,如果try语句中未验证条件,则返回标识符?

这是我的案例:

 int Automat::Retragere()
{
    int suma;
    cout<<"n Introduceti suma pe care doriti s-o retrageti: ";
    cin>>suma;
    if(suma > 5000){
        throw "n Suma este mai mare decat plafonul maximal zilnic.";
    }
    else{
        if(suma > sold){
            throw "n Suma este mai mare decat SOLDUL curent.";
        }
        else{
            cout<<"Operatiune efectuata cu succes.";
            sold = sold - suma;
            return 1;
        }
    }
}
marcaj2:
//code here
    switch(optiune){
    case 1:
        Retragere();
        goto marcaj2;
    case 2:
        Depunere();
        goto marcaj2;
    case 3:
        Transfer();
        goto marcaj2;
    default:
        break;
    }

我在问,在调用"Retragere"函数后,如果try遇到错误,是否有可能返回到我的标识符。

在您演示的情况下,Automat::Retragere可能不应该抛出任何异常,而应该返回描述错误的错误代码,因为"输入太大"(大于允许值或大于帐户总和)并不是真正的异常状态。使用一个带有说出名称的枚举,而不是普通的int。有了一个简单的返回值,你就可以自由地使用普通的控制流,比如while循环输入,直到数字被允许为止。

设计插曲:如果这是一个期望经过净化的输入的例程,那么这些条件表明程序错误,那就不一样了。事实上,在这个阶段,可能已经将数据采集与业务逻辑分开了。

这意味着一个函数负责获取输入并对其进行检查;另一个函数需要有效的输入(没有字符串,而是一个指示有效金额的数字),并执行实际的业务操作,如提款或存款。这只是一句话,但在现实世界中可能涉及建立某种连接、身份验证等。

当提供一个无效的数字时,业务函数可能会抛出,因为数据提供程序违反了其约定。

关于你的问题的技术方面:2011年标准在15/3:中说

goto、break、return或continue语句可用于传输try块或处理程序之外的控件。

我无法想象有任何普通的理由这样做,但这并不违法。(围绕goto的一些规定,甚至可以说是goto本身,目标机器生成的代码或类似场景。)

很可能在本地处理某些异常;一种更明智的方法(比直接从catch块内部到函数中某个地方的goto更明智)是将try/catch块放在循环中。catch块将检查异常,并设置一个错误代码,然后在循环条件中进行检查,或者可能重新抛出未知或严重到无法从本地恢复的异常。

这就是您想要的吗?

bool done = false;
while (!done)
{
    //marcaj2:
    switch(optiune){
    case 1:
        Retragere();
        break;        // break out of the switch, i.e. will continue at while (!done)
                      // so it similar to goto marcaj2
    case 2:
        Depunere();
        break;
    case 3:
        Transfer();
        break;
    default:
        done = true;   // end the while loop
        break;
    }
}

其他人已经评论说异常抛出很糟糕。

但如果你真的想要它,我想你可以这样做:

bool done = false;
while (!done)
{
    try
    {
        //marcaj2:
        switch(optiune){
        case 1:
            Retragere();
            break;        // break out of the switch, i.e. will continue at while (!done)
                          // so it similar to goto marcaj2
        case 2:
            Depunere();
            break;
        case 3:
            Transfer();
            break;
        default:
            done = true;   // end the while loop
            break;
        }
    }
    catch (...)
    {
        // error handling...
    }
}