我正在为我正在开发的 C++ 应用程序编写一个小的异常类层次结构,并且我无法从std::runtime_error
. 这是类似于我到目前为止所写的代码:
class RuntimeException : public virtual boost::exception, public virtual std::runtime_error {
public:
virtual ~RuntimeException() {}
RuntimeException() : runtime_error("A RuntimeException occurred.") {}
RuntimeException(const std::string& what) : runtime_error(what) {}
};
class IllegalArgumentException : public virtual RuntimeException {
public:
IllegalArgumentException() : RuntimeException("An IllegalArgumentException occurred.") {}
IllegalArgumentException(const std::string& what) : RuntimeException(what) {}
};
该类RuntimeException
编译没有问题,但IllegalArgumentException
拒绝在 VS2015 上编译,产生错误:no default constructor exists for class "std::runtime_error"
对于IllegalArgumentException
. 这挑战了我对 C++ 继承层次结构的理解,因为我希望这段代码编译得很好。
我的理解是IllegalArgumentException
应该编译,因为虽然std::runtime_error
确实没有默认构造函数,但它的构造函数正在被构造函数调用RuntimeException
。但显然这一定是错误的,因为编译器拒绝它。似乎希望我std::runtime_error
直接从IllegalArgumentException
构造函数调用构造函数(当我这样做时编译器错误消失了),但这似乎是错误的,因为那样我会调用构造函数std::runtime_error
两次:一次在构造函数中RuntimeException
,然后再次在的构造函数IllegalArgumentException
。
这样做安全和/或有效吗?如果不是,为什么编译器似乎鼓励它?我可以将自己作为成员变量派生std::exception
并实现std::string
,但我认为从已经实现了这一点的标准类派生会更容易。这是错误的做法吗?此外,我实际上是从两者中获得boost:exception
并std::runtime_error
为这个问题做出贡献的事实吗?