当一个类继承自同一个基类的 2 个类时,我无法理解为什么虚拟继承在我们没有遇到类似于钻石问题的问题的情况下有用。
当它仍然有用(或什至需要)时,有人可以给我一个例子或解释吗?
谢谢:)
当一个类继承自同一个基类的 2 个类时,我无法理解为什么虚拟继承在我们没有遇到类似于钻石问题的问题的情况下有用。
当它仍然有用(或什至需要)时,有人可以给我一个例子或解释吗?
谢谢:)
当没有潜在的菱形继承问题时,虚拟继承并不是很有用。这个问题就是虚拟继承要解决的问题。以奇怪的对象布局和从大多数派生类调用最顶层的基础初始化为代价。
虚拟继承最常见的实际应用是接口。
通过虚拟继承,您可以在实现中使用 Java 继承技术。
在 C++03 中有额外的虚拟继承用例,基于需要从最派生的类初始化最顶层类的黑客攻击。
这些用例包括:
使类不可继承。
由final
C++11 解决。
强制使用特定的最派生类(模板化)。
在 C++11 中,协变功能(例如clone
成员函数)可以通过 C++11 构造函数参数转发更容易地通过中间人继承添加。
“有用”是一个主观词。它对某些人来说足够有用,因为它是 C++ 中的一个语言特性,但对于其他人来说,它不够用,因为 Java 没有它。接口是类似的东西,但不完成同样的事情。
常见的成语是mixin。您保留了常规的类层次结构,但您也从另一个提供一些额外(mixin?)功能的类继承。因此,您不要使用它,以便您的类可以像其父类一样表现,而只是为了实现。
这对我来说似乎是一件有用的事情。但是,这是主观的。
是的,在 c++11 之前的时代,virtual
继承对于实现final
类似的机制很有用。
// template style may not work with clang++
template<class T> struct Wrap { typedef T type; };
template<class Derived> class Final { // no one should inherit `D` from hereon
Final () {}
friend class Wrap<Derived>::type;
};
class D : virtual Final<D> {}; // `virtual` inheritance
class D2 : public D {}; // if anyone tries to still inherit `D`
int main () {
D d;
D2 d2; // <--- an expected error occurs upon object declaration
}
请参阅 Bjarne Stroustrup 的页面以获得更简单但有限的方法: 我可以阻止人们从我的课程中派生吗?