我很确定这里有类似的问题,但我找不到它。
假设我有几个函数,可能抛出整个异常层次结构 - 假设 N 类型的异常类。
现在,有没有一种很好的方法可以处理所有这些异常,而不是用 N catch
- 块编写相同的代码几次?
我实现这个(非常难看)的方式是使用宏。其他想法?
所有函数都有不同的输入/输出参数和返回类型
修改
是的,所有异常都具有相同的基类 - 它是一个层次结构。但是不同的类有不同的附加信息。
示例:
try
{
object->execute( ... );
}
catch( type1& ex )
{
// ...
}
//...
catch( typeN& ex )
{
// ...
}
// some other code
// and again:
try
{
object->do_something_else( ... );
}
catch( type1& ex )
{
// ...
}
//...
catch( typeN& ex )
{
// ...
}
// and so on
答案 0 :(得分:3)
创建一个名为handleExceptions(Exception&)
的函数,该函数引用异常的基类。
在该功能中,您可以做任何您想要的例外情况,例如:调用一些特定于Exception
子类的虚方法。您还可以使用dynamic_cast
等来定义实际的异常。
答案 1 :(得分:2)
已经提到了通过基类捕获并向handleException方法提供异常,该方法然后切换实际的基础类型。这是另一种方法,反过来说:
您可以编写一个函数exception_check
,它接受一个仿函数并将其嵌套在相应的try..catch
内:
template<typename Func>
Func exception_check(Func fun)
{
try
{
func();
}
catch( type1& ex )
{...}
//...
catch( typeN& ex )
{...}
return func; //in case the functor stores a result.
}
当然,为了使这个工作没有生成的代码看起来丑陋丑陋,你可能需要C ++ 11及其lambda函数,否则你会将代码分散到很多仿函数上。使用lambda函数,它可以简单地称为
exception_check([&](){ object->execute(...); });
exception_check([&](){ object->do_something_else(...); });
就个人而言,我发现这个更好看,然后在每个函数调用周围进行一次尝试/捕获。
当然在c ++ 11中,为仿函数使用完美转发而不是复制它可能是个好主意。
答案 2 :(得分:1)
traget函数的每次调用都应该有自己的try块,除非你可以将这些调用组合成一个带有开关的函数。
您可以捕获基类并调用将使用typeid
操作或任何其他方式的常用函数来区分内部可能的异常类型。由于异常应该很少发生,因此使用RTTI的开销可能是可接受的。