试图了解使用虚拟基类继承的影响,尤其是在运行时成本方面。我想到的情况还涉及接口(interface)(或ABC)。

   I----------
 / | \        |
D1 D2 D3      Isub
      |     /
      D3Dec

因此,我们有一个接口(interface)I,我们有不同的实现D1D2D3。但现在的问题是,有一个特殊的装饰器,它仅包装了一些(任意)I实现,然后根据通过I表示的协定添加了扩展功能。

因此,从逻辑或设计的 Angular 来看,希望通过从Isub派生的子接口(interface)I来表达这种扩展能力。因此,任何Isub也会自动履行I契约(Contract)。

问题:性能影响

现在,要在C++中实现这种功能,必须完成I接口(interface)virtual的任何实现,并且类似地,Isub必须从virtual继承I,否则我们最终将在I中驻留两个D3Dec子对象。
  • 这是否意味着I的每个实现都必须通过棘手的虚拟基本偏移调整来付出内存布局方面的代价。正确?
  • IIsub都是纯虚拟的,即没有成员而只有纯虚函数时,
  • 的情况有所不同吗?那么有可能在没有虚拟继承的情况下进行这项工作吗?
  • 需要注意的棘手问题是,当客户端代码仅获得对Isub的引用时。如果客户端调用扩展功能,则他们实际上会在D3Dec中调用该功能的实现,而这反过来又使用其他I -functionity来实现扩展功能,因为显然D3dec对装饰的具体I-实现一无所知。这是否必然意味着我们必须使用虚拟继承?还是有任何基于模板的技巧来解决这个问题,但仍然有一个(抽象的)子接口(interface)Isub

  • 当然,显而易见的替代方法是切断IIsub之间的链接,将其转变为琐碎的混合。这是可行的,但是很丑陋,因为Isub独立于I并没有多大意义。两者甚至都在签名上使用相同的数据类型,等等。

    最佳答案

    通过使接口(interface)类成为具体类的模板参数,可以完全避免菱形继承(钻石问题)问题。这样就不再需要虚拟类继承。

    class I { ... };
    
    template<class Ifc>
    class D3Impl : public Ifc
    { ... };
    
    typedef D3Impl<I> D3;
    
    class Isub : public I { ... };
    
    class D3Dec : public D3Impl<Isub>
    { ... };
    

    关于c++ - 从接口(interface)进行虚拟继承的成本,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47722508/

    10-12 19:34