在不更改用户代码的情况下继承std :: exception

问题描述 投票:1回答:1

目前在我们的API中,我们有自己的异常类型MyException,它不会(既不直接也不间接)从std::exception或任何其他类型继承:

class MyException {
public:
    MyException(std::string const& message);
    std::string const& GetErrorMessage() const;
private:
    //...stuff, e.g. like the error-message.
};

对于我们的客户(以及我们自己的开发人员),这导致总是向try-block添加至少两个catch-handler的负担:

try {
    SomeLibraryFunction();
}
catch (MyException const& e) { std::cerr << e.GetErrorMessage(); }
catch (std::exception const& e) { std::cerr << e.what(); }

为了减少catch-handler的数量,我想从std::exception添加继承。但问题在于它会“破坏”现有代码。即编译器将选择与之前不同的catch-handler:

try {
    SomeOtherLibraryFunction();
}
catch(std::exception const& e) { std::cerr << "STD-EX"; }
catch(MyException const& e)
{
    std::cerr << "LIBRARY-EX";
    ExecuteMandatoryCodeWhenMyExceptionGetsThrown(e);
}

一旦MyExceptionstd::exception继承,第二个抓手将永远不会到达。其原因是here

当复合语句中的任何语句抛出类型E的异常时,它将根据handler-seq中每个catch子句的形式参数T的类型与列出catch子句的顺序进行匹配。

有没有一种方法,编译器将采用最佳匹配的catch子句而不是第一次匹配?或者任何其他方式从std::exception实现继承而不更改将调用哪个catch-handler?

c++ api-design
1个回答
1
投票

最安全的方法是在这种情况下将异常类型更改为新类型,例如MyExceptionV2,教育人们它会好得多,并且MyException最终会被弃用。然后给他们时间升级他们的catch块以使用你的新类型并删除额外的catch块。然后在下一个版本中弃用它,然后在更高版本中删除MyException

© www.soinside.com 2019 - 2024. All rights reserved.