我正在使用QT 4.8(C ++)进行桌面应用程序项目,并编写异常处理,如下所示:
void callerMethod()
{
try
{
method1();
}
catch(Exception1& e)
{
// display critcal error message
// abort application
}
catch(std::Exception& e)
{
// print exception error message
}
catch(...)
{
// print unknown exception message
}
}
void method1()
{
try
{
// some initializations
// some operations (here exceptions can occur)
// clean-up code (for successful operation i.e no exception occurred)
}
catch(Exception1& e)
{
// clean-up code
throw e;
}
catch(Exception2& e)
{
// clean-up code
throw e;
}
catch(Exception3& e)
{
// clean-up code
throw e;
}
catch(...)
{
// clean-up code
throw;
}
}
所以我的问题是我需要在每个catch块中编写清理代码吗? 有什么方法可以避免编写重复的代码?
注意 :: [在method1()]我想重新抛出发生的异常 我的来电者。所以我无法在单一的捕获区中捕获它们, 因为那时类型信息将会丢失。
答案 0 :(得分:8)
Method1可以通过两个概念大大简化:
throw
,您无需了解抛出的异常类型。因此,method1()
应如下所示:
void method1()
{
// some initializations of RAII objects
// some operations (here exceptions can occur)
}
如果您从catch
派生Exception1,则可以删除callerMethod
中的第一个std::exception
子句,因为what()
方法是虚拟的。
答案 1 :(得分:1)
您应该尽可能地抛出异常,并在调用链中尽可能高地捕获它们。这会自动减少代码重复,并集中处理错误。你在一个地方投掷/捕捉,这似乎有点......被迫。
我经常做这种事情(特别是对于程序结束例外:
int main()
try
{
function_calls_that_may_throw();
// ...
}
catch(my_exception& e)
{
e.do_exception_stuff();
}
catch(std::exception& e)
{
std::cout << e.what();
}
catch(...)
{
std::cout << "Something bad happened.\n";
}
这只能用于抛出您不打算更好地处理的异常或重试失败的操作等。
这种方法的专家是所有/大多数错误处理代码都在程序的顶层,并且调用链中的所有函数都不必担心这些东西,他们所做的只是当他们有这种感觉时抛出异常。
答案 2 :(得分:0)
如果所有清理代码完全相同,则可以执行catch(...)块中的所有操作:
try {
// code
} catch (...) {
// cleanup
throw;
}
如果您的代码略有不同,您可以随时调用清理功能:
try {
// code
} catch (exc1 ex) {
cleanup(args);
// exc1 specific
throw;
} catch (exc2 ex) {
cleanup(args);
// exc2 specific
throw;
} catch (...) {
cleanup(args);
throw;
}