gpt4 book ai didi

c++ - 从没有默认构造函数的虚拟基类派生类

转载 作者:行者123 更新时间:2023-11-30 03:38:02 24 4
gpt4 key购买 nike

我正在为我正在开发的 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 的构造函数正在调用构造函数。但显然这一定是错误的,因为编译器拒绝了它。似乎要我直接从 IllegalArgumentException 构造函数调用 std::runtime_error 构造函数(当我这样做时编译器错误消失),但这似乎是错误的,因为那时我会调用 std::runtime_error 的构造函数两次:一次是在 RuntimeException 的构造函数中,另一次是在 IllegalArgumentException 的构造函数中。

这样做安全和/或有效吗?如果不是,为什么编译器似乎鼓励它?我可以只是派生自std::exception 并将std::string 自己实现为成员变量,但我认为这会更容易从已经实现它的标准类派生。这是错误的做法吗?此外,我实际上是从 boost:exceptionstd::runtime_error 派生的事实是否导致了这个问题?

最佳答案

当使用virtual 继承时,virtual 基类的构造函数调用是最派生类的责任,而不是任何中间类的责任类(class)。原因很明显:virtual 继承的使用表明期望实际上有多个派生类使用基类。这些派生类中的哪一个将负责构建虚拟 基?

因此,任何派生类的构造函数都需要为 virtual 基提供一个参数,例如:

IllegalArgumentException::IllegalArgumentException(std::string const& what)
: std::runtime_error(what)
, RuntimeException(what) {
}

为了避免中间基类调用用于virtual 继承的virtual 基类的构造函数,通常会提供一个默认构造函数。当然,这带来了这样一种可能性,即大多数派生类错误地依赖于由其基类之一调用的正确构造函数。

关于c++ - 从没有默认构造函数的虚拟基类派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39820001/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com