【发布时间】:2015-01-07 16:57:46
【问题描述】:
我们的基本情况如下:
// 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,不与来自 3rd 方库的任何错误有任何关系,但只是在相同的上下文中抛出使用 3rd 方库中的东西的地方。
// 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;
我们现在已经考虑“反转”层次结构以更好地反映实际情况,并且这样做(最初)对其他代码的影响最小。
我们计划这样做:
// 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 的非虚拟继承有多少会搞砸。我认为我们在运行时绑定as long as noone tries to catch(std::exception const&) in which case the catch would fail 是安全的,因为转换是不明确的。
这似乎是一个可行的解决方案?或者尝试将non-virtual-std::exception 类型与上述层次结构集成是一个“非常糟糕的主意”?
注意:我们可以更改第 3 方库以从 std::exception 中“正确”派生 virtual 的可能性为零(如在 0.00% 中)。
- 当然,如果之前版本中的任何
catch(ns3p::OperationException&)“意外”捕获了InvalidXYZExecption,这将在现在中断,但这是可以接受的。
【问题讨论】:
-
为什么需要这么多异常类,为什么需要 ModuleOpException 派生自第 3 方库异常类?
标签: c++ exception exception-handling multiple-inheritance