【问题标题】:abc interface inheritance and re-exposing methods in base classabc 接口继承和基类中的重新公开方法
【发布时间】:2011-07-16 09:23:19
【问题描述】:

我很好奇是否有一种巧妙的方法可以在派生接口的基类中公开方法。

所以在代码中:-

class cbase {
public:
  void MyMethodA() { }
};

class cderived : public cbase {
public:
  void MyMethodB() { }
}

class ibase { 
public:
  virtual void MyMethodA() = 0;
};
class iderived : public ibase {
public:
  virtual void MyMethodB() = 0;
};

现在如果我让 cbase 继承 ibase,而 cderived 实现 iderived,编译器会抱怨当我实例化 cderived 时,MyMethodA() 是抽象的,没有实现。

MyMethodA() 在基类中通过 ibase 实现。解决这个问题的唯一方法是在 c 派生类中重新实现 ibase 的方法吗?如果是这样,糟糕!

如下:-

class cbase : public ibase {
public:
  void MyMethodA() { }
};

class cderived : public cbase, public iderived {
public:
  void MyMethodA() { cbase::MyMethodA(); }
  void MyMethodB() { }
};

cderived inst;
iderived *der = &inst;  
der->MyMethodA();
der->MyMethodB();
ibase *bas = der;
bas->MyMethodA();

我希望这足以传达问题。 :) 当我们试图重构旧代码时,这听起来可能有点循环。

我相信那里有很多热切的评论;)

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

    如果我理解正确,您想让ibase 成为iderivedcbase 的虚拟基类。

    这是在类层次结构中每个接口类只有一个实例,当您在cderived 级别将cbaseiderived 连接在一起时,@987654329 中的MyMethodA 的非虚拟覆盖使用 @ 是因为它是 主导 覆盖。

    请看这里:Hidden Features of C++?

    例如

    class ibase { 
    public:
      virtual void MyMethodA() = 0;
    };
    class iderived : public virtual ibase {
    public:
      virtual void MyMethodB() = 0;
    };
    
    class cbase : public virtual ibase {
    public:
      void MyMethodA() { }
    };
    
    class cderived : public cbase, public virtual iderived {
    public:
      void MyMethodB() { }
    };
    
    int main()
    {
        cderived inst;
        iderived *der = &inst;  
        der->MyMethodA();
        der->MyMethodB();
        ibase *bas = der;
        bas->MyMethodA();
    }
    

    【讨论】:

    • iderived 和 cbase 不需要从它们的基类虚拟继承,不是吗?
    • @VJo:我不明白你的问题,对不起。
    • 哇,所以我只是忽略了 visual-c 中的优势警告,这都是 honky-dory 吗?我印象深刻:)
    • 换句话说:为什么会这样:class iderived : public virtual ibase?为什么不只是class iderived : public ibase
    • @VJo: ibase 实际上是接口类。如果在类层次结构的两个点上它都不是虚拟基类,那么将有两个基类副本,并且需要在继承树的两个分支中覆盖 MyMethodA。如果ibase 不是iderived 的虚拟基类,那么MyMethodAcbase 实现将不会覆盖ibase 副本,它是iderived 的非虚拟基类。
    【解决方案2】:

    看看multiple inheritance

    该常见问题的答案基本上是对您的问题的回答:

    class cderived : public virtual cbase {
    public:
      void MyMethodB() { }
    }
    
    class ibase { 
    public:
      virtual void MyMethodA() = 0;
    };
    class iderived : public virtual ibase {
    public:
      virtual void MyMethodB() = 0;
    };
    

    【讨论】:

    • 我认为问题的重点是找到一种方法来避免必须实现MyMethodA 的“直通”版本。
    猜你喜欢
    • 2017-12-29
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 2012-11-15
    • 2021-09-19
    相关资源
    最近更新 更多