2012-04-13 23 views
4

我目前有一些代码,我想重构。大量的异常对于所有异常都有一些共同的代码,并且对于每种特定的异常类型需要分别处理一些特定的代码。我想弄清楚如何摆脱每个catch区块的公共部分。一个想法是这样做的:处理异常的共同部分在一起

try { 
    /* Stuff that may fail */ 
} catch(const std::exception &) { 
    /* do common part here */ 
    try { throw; } 
    catch(const exception1 &) { 
    /* do stuff for exception1 here */ 
    } 
    catch(const exception2 &) { 
    /* do stuff for exception2 here */ 
    } 
} 

然而,这让我觉得有点难看。

有没有更好的方法来分解这个共同的逻辑,或者是否有一个完全避免这种尝试的理由?

回答

3

一般来说,try/catch应该只在人烟稀少的代码出现。问题在于,例如,在提前退货的情况下,也应该多次执行catch条款中的操作。

Idiomatic C++广泛使用RAII来避免需要在catch子句中进行清理的情况,这通常会消除大部分工作。

现在,你的模式不是那么糟糕本身,它确实包含了常见的东西。但是这些常见的东西可能会自动处理。

在我偶然发现的所有代码库中,只有几次我看到catch条款的真实使用,请勿将其用作离合器。

3

一大组的异常有一些共同的代码

移动普通代码的函数或方法。从每个catch调用方法。就像消除任何其他重复一样;存在try .. catch没有区别。


编辑

但如果你关注“大集例外” 真的,真正的问题可能是你有一个大集例外。为什么不同的例外需要不同的处理?真的只有例外事件使用例外吗?

+2

这与我现在(在代码中,而不是在问题中)非常相似。然而,这意味着我将在每个异常中调用此方法,并且如果有人稍后添加异常并忘记该调用将会确保。这个bug可能会被忽略很长一段时间,因为条件是,呃,例外,因此将很少被处理。因此我正在寻找一种让后来的开发人员更安全的好方法。 – LiKao 2012-04-13 12:07:00

+0

“如果有人后来添加了一个异常并忘记了调用”,但批评适用于您使用的任何*计划:稍后的程序员可能会错误地改变它。如果公共代码被抽象为一个函数,后面的程序员很清楚该函数应该针对每个“catch”被调用。 – Raedwald 2012-04-13 15:21:55

+0

是的,我同意可以错误地更改任何方案。然而,对我而言,问题往往是错误的发生是多么的容易。如果您可以在代码保持不变的情况下添加其他地方的其他地方,这很难出错。如果你必须弄清楚一些特殊的东西,然后才能添加一个例外,那么人们可能会很可能会错过这个例外。在其中一种情况下,你只能通过在另一种情况下主动改变某些东西来破坏东西,通过忘记某些东西来搞乱东西。第二种情况通常是更糟糕的恕我直言。 – LiKao 2012-04-16 08:14:17

0

我真的只是将通用代码移动到一个函数。

这里是另一个想法:

try { 
    /* Stuff that may fail */ 
} catch(const std::exception & e) { 
    /* do common part here */ 
    if (const exception1 * e1 = dynamic_cast<const exception1*>(&e) { 
    /* do stuff for exception1 here */ 
    } else if (const exception2 * e2 = dynamic_cast<const exception2*>(&e) { 
    /* do stuff for exception2 here */ 
    } else 
    throw; 
} 
+0

您的解决方案都不是很好的编码练习。很多人不理解异常的处理,所以保持简单。您的“特殊”处理不会很好理解,并且可能无法正确维护。 – 2012-04-13 12:36:54