2012年3月20日星期二

[C++]注意捕捉异常列表顺序

[C++]注意捕捉异常列表顺序
  -- throw 异常,catch异常的列表顺序

话说有图有真相,那么为了描述该问题(catch 异常列表顺序问题),我特地编写一段简单代码示例以说明该问题,或曰“有代码有真相”呵呵,莫扯了,开始吧。




问题说明:catch 异常列表顺序影响最后真正抓取异常情况,即处理异常的catch分支。

建议:在异常catch列表,异常子类(派生类)的处理需(应该)置于其异常基类处理之前!
针对违法该规则(建议)情况,异常基类处理置于异常子类之前,有些编译器会给予友情的警告提示,如下:
warning: exception of type 'derived_class' will be caught|
warning:    by earlier handler for 'base_clase'|


详见下面的两个简单例子,说明上面描述的问题与建议,示例如下:



    /// 1-1.
    try
    {
        std::cout << " throw a exception2.\n";
        throw exception2();
    }
    catch (const exception1& e)
    {
        std::cout << " catch (const exception1& e).\n";
        std::cout << " catch "<< e.what() << "\n";
    }
    catch (const exception2& e)
    {
        std::cout << " catch (const exception2& e).\n";
        std::cout << " catch "<< e.what() << "\n";
    }


    /// 1-2.
    try
    {
        std::cout << " throw a exception2.\n";
        throw exception2();
    }
    catch (const exception2& e)
    {
        std::cout << " catch (const exception2& e).\n";
        std::cout << " catch "<< e.what() << "\n";
    }
    catch (const exception1& e)
    {
        std::cout << " catch (const exception1& e).\n";
        std::cout << " catch "<< e.what() << "\n";
    }
    /// ---
    /// 2-1.
    try
    {
        std::cout << " throw a logic_error.\n";
        throw std::logic_error("a logic_error");
    }
    catch (const std::logic_error& e)
    {
        std::cout << " catch (const logic_error& e).\n";
        std::cout << " catch "<< e.what() << "\n";
    }
    catch (const std::exception& e)
    {
        std::cout << " catch (const exception& e).\n";
        std::cout << " catch "<< e.what() << "\n";
    }


    /// 2-2.
    try
    {
        std::cout << " throw a logic_error.\n";
        throw std::logic_error("a logic_error");
    }
    catch (const std::exception& e)
    {
        std::cout << " catch (const exception& e).\n";
        std::cout << " catch "<< e.what() << "\n";
    }
    catch (const std::logic_error& e)
    {
        std::cout << " catch (const logic_error& e).\n";
        std::cout << " catch "<< e.what() << "\n";
    }





[Output],上面代码输出结果,如下:
throw a exception2.
catch (const exception1& e).
catch an exception2.
throw a exception2.
catch (const exception2& e).
catch an exception2.
throw a logic_error.
catch (const logic_error& e).
catch a logic_error
throw a logic_error.
catch (const exception& e).
catch a logic_error


所以,[C++]注意捕捉异常列表顺序,在异常catch列表,异常子类(派生类)的处理需(应该)置于其异常基类处理之前。


最后,附上如上两例子的完整测试在吧(可参考),放在 github

(完)





没有评论:

发表评论