从 std::exception 继承而不更改用户代码
Inherit from std::exception without changing users code
目前在我们的 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 块添加至少两个 catch 处理程序的负担:
try {
SomeLibraryFunction();
}
catch (MyException const& e) { std::cerr << e.GetErrorMessage(); }
catch (std::exception const& e) { std::cerr << e.what(); }
为了减少 catch-handler 的数量,我想添加对 std::exception
的继承。但问题在于它将 "break" 现有代码。也就是说,编译器将选择一个与之前不同的 catch-handler:
try {
SomeOtherLibraryFunction();
}
catch(std::exception const& e) { std::cerr << "STD-EX"; }
catch(MyException const& e)
{
std::cerr << "LIBRARY-EX";
ExecuteMandatoryCodeWhenMyExceptionGetsThrown(e);
}
一旦 MyException
从 std::exception
继承,第二个 catch-handler 将永远不会被访问。原因是 here:
When an exception of type E is thrown by any statement in compound-statement, it is matched against the types of the formal parameters T of each catch-clause in handler-seq, in the order in which the catch clauses are listed.
有没有办法让编译器采用最匹配的 catch 子句而不是采用第一个匹配项?或者任何其他方式实现从 std::exception
的继承而不改变将调用哪个 catch-handler?
在这种情况下,最安全的方法是将异常类型更改为新类型,例如MyExceptionV2
,教育人们它要好得多,并且 MyException
最终会被弃用。然后给他们时间升级他们的 catch 块以使用您的新类型并删除额外的 catch 块。然后在下一个版本中弃用它,然后在以后的版本中删除MyException
。
目前在我们的 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 块添加至少两个 catch 处理程序的负担:
try {
SomeLibraryFunction();
}
catch (MyException const& e) { std::cerr << e.GetErrorMessage(); }
catch (std::exception const& e) { std::cerr << e.what(); }
为了减少 catch-handler 的数量,我想添加对 std::exception
的继承。但问题在于它将 "break" 现有代码。也就是说,编译器将选择一个与之前不同的 catch-handler:
try {
SomeOtherLibraryFunction();
}
catch(std::exception const& e) { std::cerr << "STD-EX"; }
catch(MyException const& e)
{
std::cerr << "LIBRARY-EX";
ExecuteMandatoryCodeWhenMyExceptionGetsThrown(e);
}
一旦 MyException
从 std::exception
继承,第二个 catch-handler 将永远不会被访问。原因是 here:
When an exception of type E is thrown by any statement in compound-statement, it is matched against the types of the formal parameters T of each catch-clause in handler-seq, in the order in which the catch clauses are listed.
有没有办法让编译器采用最匹配的 catch 子句而不是采用第一个匹配项?或者任何其他方式实现从 std::exception
的继承而不改变将调用哪个 catch-handler?
在这种情况下,最安全的方法是将异常类型更改为新类型,例如MyExceptionV2
,教育人们它要好得多,并且 MyException
最终会被弃用。然后给他们时间升级他们的 catch 块以使用您的新类型并删除额外的 catch 块。然后在下一个版本中弃用它,然后在以后的版本中删除MyException
。