我们的基本情况如下所示:
// 3rd party lib:
namespace ns3p {
class OperationException : public std::exception; // yes, no `virtual` here
}
// our code:
// wrapper with additional information to the ns3p::OperationException
class ModuleOpException : public ns3p::OperationException;
// our catch sites:
// mostly:
catch (ModuleOpException const& ex) { ...
// but sometimes:
catch (ns3p::OperationException const& ex) { ...
现在,这增加了额外的异常,所有异常都源自 ModuleOpException
,不与来自第 3 方库的任何错误有任何关系,但只是在使用第 3 方库的内容的相同上下文中抛出。
// This indirectly derives from ns3p::OperationException, even though
// there is *no* underlying OperationException at all. It just thrown "stand alone"
// and caught by ModuleOpException& :
class InvalidXYZException : public ModuleOpExcpetion;
我们现在考虑“反转”层次结构以更好地反射(reflect)实际情况,并且这样做(最初)对其他代码的影响最小。
我们计划这样做:
// new base exception type:
class ModuleBaseException : public virtual std::exception;
// changed to derive both from our base type as well as the 3rd party type:
class ModuleOpException : public virtual ModuleBaseException, public virtual ns3p::OperationException;
// only derives from the base type:
class InvalidXYZException : public virtual ModuleBaseException;
// all catch sites change the catch of `ModuleOpException` to:
catch (ModuleBaseException const& ex) { ...
// and leave the catch ns3p::OperationException alone
这应该有效(应该吗?),除了我不确定第三部分异常的 std::exception
的非虚拟继承有多少type 会把事情搞砸。我认为我们很安全as long as noone tries to catch(std::exception const&)
in which case the catch would fail在运行时绑定(bind),因为转换不明确。
这看起来是一个可行的解决方案吗?还是尝试将 non-virtual-std::exception
类型与上述层次结构集成是一个“非常糟糕的主意”?
注意:我们可以更改第 3 方库以使用来自 std 的 virtual
“正确”派生的可能性为零(如 0.00%
)::异常。
- 当然,如果之前版本中的任何
catch(ns3p::OperationException&)
“不小心”捕获了InvalidXYZExecption
,这现在会中断,但这是可以接受的.
最佳答案
try...catch 应该发生在异常将被正确处理的地方,或者如果异常将在此时被修改并重新抛出。
使用不同的异常类的目的是为了以不同的方式处理它们。 (我认为这是一个坏主意,打开某种代码会更好,并且您可能仅在极少数情况下才根据类型更改您的操作,例如如果错误是暂时的则重试请求)。
无论如何,我假设第 3 方库用于帮助实现您自己的库。您的库的用户不想知道您用于实现的库的异常。
因此,您应该从您的库的用户那里抽象出来,通过捕获它们中的任何一个并将它们作为您自己的重新抛出,以用户期望的方式。
从您的库中抛出的异常与您的函数的返回值一样都是“契约”的一部分。
因此,用户可能希望捕获 ModuleBaseException 或 ModuleOpException 而不是 ns3p::OperationException。
您自己的代码应该捕获它们,可能会将它们转换为您的 ModuleOpException 类型并抛出它。
关于c++ - 在 C++ 的异常层次结构中引入额外的基类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27824543/