定制异常层次结构 来自std :: exception和std :: bad_alloc的可怕钻石

Dan*_*iel 6 c++ polymorphism exception multiple-inheritance c++11

我在自己的异常层次结构中存在继承问题.

该类Exception具有非常好的功能(回溯,日志记录,...),因此它是我的任何异常的基类.它继承自我std::exception在许多网页中看到的建议.此外,我正在使用一个单元测试框架来报告任何std::exception意外抛出.但最后说,这只是为了方便.

然后,我有一个新OutOfMemoryException类,它将由自定义new_handler抛出.此类继承自Exception但仍继承std::bad_alloc与现有代码的兼容性.我猜这更重要,因为new不会再扔std::bad_alloc了.

这里的问题是显而易见的:既然std::bad_alloc来自std::exception,我有一个可怕的钻石情况.

class Exception : public std::exception { };
class OutOfMemoryException : public Exception, public std::bad_alloc { };
Run Code Online (Sandbox Code Playgroud)

遗憾的是,正如你在这里看到的stackoverflow.com ...标准异常不是虚拟继承,所以std::exception是一个模糊的基类.

然后:

  1. 有可能以任何方式解决这个问题吗?(我不知道,任何课程或模板技巧)

  2. 如果不是,最好Exception不能继承std::exceptionOutOfMemoryException确实std::bad_alloc

由于其许可许可,我可以破解单元测试框架.

提前谢谢你,对不起,我不是一个很好的英语演讲者.

小智 0

并不是说这个解决方案很漂亮,但它可能足以满足您的需求。假设std::exception定义了一个名为 的函数func1()。当然,您将从继承中的两个路径中获取它,并且任何调用都会为OutOfMemoryException::func1()您提供有关不明确基类的编译时消息。

所以这是一个hacky且不太漂亮的解决方案。覆盖其中一个版本的非虚函数std::exception并仅转发其中一个版本。两者任Exception::func1()std::bad_alloc::func1()

我确实意识到这很丑陋,因为您正在重写非虚拟函数。如果重写函数采用参数,您还会面临完美转发问题。如果您不小心,可能会复制您不想复制的内容等。但它应该允许您从 std::exception 调用成员函数。