【问题标题】:Handling errors in a loop gracefully优雅地处理循环中的错误
【发布时间】:2015-02-25 16:20:49
【问题描述】:

我正在遍历列表并转换列表中的每个项目(文件名)。如果没有错误,我会为文件显示绿色图标,否则为红色。我下面的代码有太多的逻辑来跟踪这个,能更好吗?

for(int i = 0; i < numFiles; i++)
{
    ......

    int allConverted = 0;

    try
    {
        convertFile( file, dest1)

        allConverted++;
    }
    catch(std::runtime_error err)
    {
        item->setIcon( QIcon("c:/code/Red.ico"));

        QMessageBox::information(this, APP_NAME, err.what(), QMessageBox::Ok, QMessageBox::Abort) == QMessageBox::Abort);
    }

    try
    {
        convertFile( file, dest2)

        allConverted++;
    }
    catch(std::runtime_error err)
    {
        item->setIcon( QIcon("c:/code/Red.ico"));

        QMessageBox::info(this, APP_NAME, err.what(), QMessageBox::Ok, QMessageBox::Abort) == QMessageBox::Abort);

    }

    if (allConverted >= 2)
        item->setIcon( QIcon("c:/code/Green.ico"));

}

【问题讨论】:

  • 编辑:您正在重复 (convertFile...allConverted...trycatch),在我看来,这是一个包含在单个 try/catch 语句中的 cicle 的尖叫
  • 我还是要运行循环,如果有错误我只需要相应地标记某些项目。
  • 此外,您可以将 allConverted++ 和 if(allconv 等折叠为: if (++allConverted >= 2) item->setIcon( QIcon("c:/code/Green.ico"));
  • 通过引用捕获异常。它们可能是多态的。

标签: c++ qt exception


【解决方案1】:

即使第一次调用失败,您是否也想尝试第二次convertFile?如果这是预期的,那么这样的东西会更干净:

for(int i = 0; i < numFiles; i++) {

    bool success = true;

    try {
        convertFile(file, dest1);
    }
    catch(const std::runtime_error& err) {
        success = false;
        QMessageBox::information(this, APP_NAME, err.what(), QMessageBox::Ok, QMessageBox::Abort) == QMessageBox::Abort);
    }

    try {
        convertFile(file, dest2);
    }
    catch(const std::runtime_error& err) {
        success = false;
        QMessageBox::info(this, APP_NAME, err.what(), QMessageBox::Ok, QMessageBox::Abort) == QMessageBox::Abort);
    }

    if (success) {
        item->setIcon(QIcon("c:/code/Green.ico"));
    }
    else {
        item->setIcon(QIcon("c:/code/Red.ico"));
    }
}

否则,可以简化为:

for(int i = 0; i < numFiles; i++) {
    try {
        convertFile(file, dest1);
        convertFile(file, dest2);
        item->setIcon(QIcon("c:/code/Green.ico"));
    }
    catch(const std::runtime_error& err) {
        item->setIcon(QIcon("c:/code/Red.ico"));
        QMessageBox::information(this, APP_NAME, err.what(), QMessageBox::Ok, QMessageBox::Abort) == QMessageBox::Abort);
    }
}

附带说明一下,异常通常应该由 const 引用(我在此处说明)来捕获,以说明多态层次结构。

【讨论】:

  • 如果两个 convertFile() 都失败了,你不会丢失第一个失败的 err.what() 吗?
  • @MichaelVincent 嗯,你这是什么意思? err 的范围受 try-catch 块的限制,那么您还想在哪里使用它?
  • 第一个给我正确的结果,比我的帖子好。我也喜欢这样一个事实,如果两个convertFilefails 中的任何一个,它都会显示警告图标,这很好。
【解决方案2】:

这个怎么样?

for(int i = 0; i < numFiles; i++)
{
    bool anyErrors = false;

    try
    {
        convertFile( file, dest1)
        convertFile( file, dest2)
    }
    catch(std::runtime_error err)
    {
        anyErrors = true;
    }

    if (anyErrors)
    {
        item->setIcon( QIcon("c:/code/Red.ico"));
        QMessageBox::information(this, APP_NAME, err.what(), QMessageBox::Ok, QMessageBox::Abort) == QMessageBox::Abort);
    }
    else        
        item->setIcon( QIcon("c:/code/Green.ico"));

【讨论】:

  • 如果 convertFile(file, dest1 失败,则不会执行 dest2 的 convertFile()。与问题中的源不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
  • 2018-11-10
  • 2021-03-11
  • 1970-01-01
  • 2020-03-19
相关资源
最近更新 更多