在几个地方处理整个异常层次结构的好方法

时间:2012-07-02 10:13:29

标签: c++ exception-handling coding-style

我很确定这里有类似的问题,但我找不到它。

假设我有几个函数,可能抛出整个异常层次结构 - 假设 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

3 个答案:

答案 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的开销可能是可接受的。