我正在为我正在开发的 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) {}
};
The RuntimeException
类编译没有问题,但是IllegalArgumentException
拒绝在 VS2015 上编译,生成错误:no default constructor exists for class "std::runtime_error"
对于两个构造函数IllegalArgumentException
。这挑战了我对 C++ 继承层次结构的理解,因为我期望这段代码能够正常编译。
我的理解是IllegalArgumentException
should编译是因为,尽管确实如此std::runtime_error
没有默认构造函数,它的构造函数被构造函数调用RuntimeException
。但显然这一定是错误的,因为编译器拒绝它。似乎要我打电话给std::runtime_error
直接从构造函数IllegalArgumentException
构造函数(当我这样做时,编译器错误就会消失),但这似乎是错误的,因为那样我会调用构造函数std::runtime_error
两次:在构造函数中一次RuntimeException
,并再次在构造函数中IllegalArgumentException
.
这样做安全和/或有效吗?如果不是,为什么编译器似乎鼓励它?我could只是源自std::exception
并实施std::string
我自己作为成员变量,但我认为从已经实现了这一点的标准类派生会更容易。这是错误的做法吗?此外,事实上我实际上是从两者中衍生出来的boost:exception
and std::runtime_error
对此问题有何贡献?
使用时virtual
继承的构造函数调用virtual
基地的责任是最衍生的类而不是任何中间类的责任。原因很明显:使用virtual
继承表明期望实际上有多个派生类使用基类。这些派生类中哪一个将负责构造virtual
base?
因此,任何派生类的构造函数都需要向virtual
基础,例如:
IllegalArgumentException::IllegalArgumentException(std::string const& what)
: std::runtime_error(what)
, RuntimeException(what) {
}
为了避免中间基调用构造函数virtual
基类用于virtual
继承通常提供默认构造函数。当然,这可能会导致最派生类错误地依赖于其基类之一调用正确的构造函数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)