非钻石类型的虚拟继承

Virtual inheritance in a non Diamond Type

本文关键字:虚拟 继承 类型 钻石      更新时间:2023-10-16

我很难理解为什么虚拟继承在我们没有遇到类似于钻石问题的情况下很有用,当一个类继承自来自同一基类的 2 个类时。

有人可以给我一个例子或解释,当它仍然有帮助(甚至需要(时?

谢谢:(

当不存在潜在的菱形继承问题时,虚拟继承并不真正有用。这个问题就是虚拟继承的全部问题。以奇怪的对象布局为代价,并从大多数派生类调用最顶层的基本初始化。

虚拟继承最常见的实际应用是接口。

通过虚拟继承,您可以在实现中使用 Java 继承技术。


在 C++03 中,虚拟继承还有其他用例,这些用例基于从最派生的类初始化最顶层类的需求。

这些用例包括:

  • 使类不可继承。
    final 在 C++11 中解决。

  • 强制使用特定的最派生类(模板化(。
    在 C++11 中,协变功能(如 clone 成员函数(可以通过中间人继承更轻松地添加,并带有 C++11 构造函数参数转发。

">

有用"是一个主观词。 它对某些人来说足够有用,因为它是C++中的一种语言功能,但对其他人来说,Java没有它还不够。 接口是类似的东西,但不完成相同的事情。

常见的成语是混合。你保留了常规的类层次结构,但你也继承了另一个提供一些附加(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的页面,了解更简单但有限的方法:我可以阻止人们从我的班级派生吗?