没有直接继承的覆盖方法实现注入

Posted

技术标签:

【中文标题】没有直接继承的覆盖方法实现注入【英文标题】:Overriding method implementation injection without direct inheritance 【发布时间】:2018-10-26 09:48:46 【问题描述】:

你们知道是否有可能将不继承任何东西的类 A 的方法的实现注入到从类 B 继承的类 C 中,该类 B 提供 A“覆盖”的虚拟方法。

基本上是这样的:

struct Base
  
    virtual void print()
      
      std::cout << " Base" << std::endl;
      
  ;

template<class T>
struct Super : public Base,
    protected T
  
  using T::print; // Do some magic here
  ;

struct Derived
  
  void print()
    
    std::cout << " Derived" << std::endl;
    
  ;

struct Derived2 : public Base
  
  void print()
    
    std::cout << " Derived2" << std::endl;
    
  ;

一个小的测试用例是:

  Super<Derived> s;
  Base* base = &s;
  std::cout << "Base with Super<Derived>: ";
  base->print();
  std::cout << std::endl;
  std::cout << "Super<Derived>: ";
  s.print();
  std::cout << std::endl;
  std::cout << "Base with Derived: ";
  Derived2 d;
  Base* baseForDerived = &d;
  baseForDerived->print();

打印出来的:

TBase with Super<Derived>:  Base

Super<Derived>:  Derived

TBase with Derived:  Derived2

理想情况下,第一个应该打印 Derived。

与 Derived2 相比,我们的目标是在没有性能损失的情况下执行此操作,因此没有虚拟继承或其他类型的间接。

PS:“T”类中不允许使用 CRTP,例如:template&lt;class C&gt; struct Derived : C ;

【问题讨论】:

刚刚编辑了我的问题 【参考方案1】:

这不是你想要的吗?

struct Base 
    virtual void print() 
        std::cout << "Base" << std::endl;
    
;

template<class T>
struct Super : Base, T 
    virtual void print() /* final */ override 
        T::print();
    
;

struct Derived 
    void print() 
        std::cout << "Derived";
    
;

struct Derived2 : Base 
    virtual void print() override 
        std::cout << "Derived2";
    
;

【讨论】:

我想就是这样。我测试了,它完全有效,没想到只是这样做,非常好。与标准派生案例相比,性能损失如何? @svoltron,优化器可以为你做很多事情,所以根据这个玩具例子真的很难说。但我不明白为什么这里应该有额外的处罚。 确实如此。我们会在一些测试后看到,但我认为你是对的。再次感谢

以上是关于没有直接继承的覆盖方法实现注入的主要内容,如果未能解决你的问题,请参考以下文章

201671010145 2016-2017 《Java程序设计》java的继承中什么叫方法覆盖,是如何实现的?

始终要覆盖toString实现可以使类用起来更加舒服

零基础学Java—继承父类并实现多个接口(二十五)

覆盖没有名称修改的继承方法[重复]

继承和抽象方法

覆盖(重写)重载。