【问题标题】:Can I partially implement an interface hierarchy?我可以部分实现接口层次结构吗?
【发布时间】:2013-12-18 14:40:06
【问题描述】:

我正在写一个类似这样的界面:

class BaseInterface
{
    virtual void MethodA() = 0;
}

class DerivedInterface : public BaseInterface
{
    virtual void MethodB() = 0;
}

我想创建一个类Derived,它是-a DerivedInterface(隐含地,是-a BaseInterface,尤其是Base)。也就是说,我只想在 Derived 类中定义 MethodB - 我想在其他地方部分指定接口(即 MethodA)。

class Base : public BaseInterface
{
    virtual void MethodA() {...};
}

class Derived : public DerivedInterface // somehow include Base as well
{
    void MethodB() {...};
}

这在 C++ 中可行吗?

【问题讨论】:

  • 忘记了virtual
  • 如果它不在Derived 的继承链中,它将无法工作,我很确定菱形链也不会在这里工作。 (即类似class Derived : public Base, public DerivedInterface
  • @Jefffrey 我做到了,谢谢 :)
  • 但真的需要吗?我的意思是虚拟关键字不是那么隐含!
  • @BhupeshPant:默认情况下,成员函数在 C++ 中是非虚函数,因此您必须明确说明它,至少在第一次声明时是这样。

标签: c++ inheritance abstract-class


【解决方案1】:

使用虚拟继承,避免成员重复:

class BaseInterface
{
    public:
    virtual void MethodA() = 0;
};

class DerivedInterface : virtual public BaseInterface
{
    public:
    virtual void MethodB() = 0;
};

class Base : virtual public BaseInterface
{
    public:
    virtual ~Base() {}
    virtual void MethodA() {};
};

class Derived : public Base, virtual public DerivedInterface
{
    public:
    virtual void MethodB() {};
};

int main() {
    Derived d;
    d.MethodA();
    d.MethodB();
}

如果没有虚拟继承,Derived 有两个 MethodA,需要在 Derived 中额外覆盖:

virtual void MethodA() override { Base::MethodA(); }

不过,这破坏了界面设计!

没有派生接口可能更简洁:

class FirstInterface;
class SecondInterface;
class Base : public virtual FirstInterface;
class Derived : public Base, virtual public SecondInterface;

这避免了重复,即使没有虚拟继承。 (为了避免麻烦,我也会使用虚拟接口继承)

【讨论】:

    【解决方案2】:

    多重继承是它的完美答案。

    class Derived : public Base, virtual public DerivedInterface
    {
        public:
        virtual void MethodB() {};
    };
    

    现在你有两个成员...

    【讨论】:

    • 这是不正确的,请参考 Dieter Lücking 的回答以了解如何做到这一点。
    • 很抱歉,您的回答仍然不正确,请参阅 Dieter Lücking 的回答以了解在何处使用虚拟继承。
    猜你喜欢
    • 2012-10-31
    • 2010-11-06
    • 2017-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-05
    相关资源
    最近更新 更多