【问题标题】:How to inherit Implementation of pure virtual function C++ [duplicate]如何继承纯虚函数C++的实现[重复]
【发布时间】:2015-11-30 18:47:58
【问题描述】:

令我惊讶的是,以下 C++ 代码无法编译。

class InterfaceA {
public:
    virtual void Foo() = 0;
};

class InterfaceB : public InterfaceA {
public:
    virtual void Bar() = 0;
};

class ImplementationA : public InterfaceA {
public:
    void Foo() override {}
};

class ImplementationB : public ImplementationA, public InterfaceB {
public:
    void Bar() override {}
};

int main() {
    ImplementationB b;
    b.Bar();
}

抽象类类型“ImplementationB”的对象是不允许的: 纯虚函数“InterfaceA::Foo”没有覆盖器。 错误 C2259 'ImplementationB': 无法实例化抽象类。

是否可以从实现A继承纯虚方法的实现而无需将实现B中的方法Foo重新定义为:

void Foo() override {
    ImplementationA::Foo();
}

如果不是,那为什么?

【问题讨论】:

  • C++ 与 Java 不同。这个问题已经被问过好几次了。
  • 我认为这里的答案比上面引用的副本中的答案要好。这些答案没有提到虚拟继承,因为另一个问题中指定的问题不像这里的问题那样从具有共同祖先的类继承。问题并不完全相同(这个问题回答了我在这里找到方法时遇到的问题,而另一个没有)。

标签: c++ inheritance abstract-class virtual c++14


【解决方案1】:

是的,要实现您的需要,您需要使用虚拟继承。

一些细节: 就像现在一样,您的 ImplementationB 有两个父级,每个父级都是 InterfaceA 的独立后代。因此,您的 ImplementationB 中有 2 个 InterfaceA 副本 - 一个是从 ImplementationA 继承并覆盖了 Foo(),另一个是从 InterfaceA 继承的,并且没有覆盖 Foo。虚拟继承(不要与虚拟函数混淆!)将确保您只有一个副本 - 一个所有内容都被覆盖的副本。

【讨论】:

    【解决方案2】:

    你有钻石问题。因此,您应该使用虚拟继承。

    正确代码:

    class InterfaceA {
    public:
        virtual void Foo() = 0;
    };
    
    class InterfaceB : public virtual InterfaceA {
    public:
        virtual void Bar() = 0;
    };
    
    class ImplementationA : public virtual InterfaceA {
    public:
        void Foo() override {}
    };
    
    class ImplementationB : public ImplementationA, public InterfaceB {
    public:
        void Bar() override {}
    };
    
    int main() {
        ImplementationB b;
        b.Bar();
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-12
      • 1970-01-01
      • 2015-08-07
      • 1970-01-01
      • 1970-01-01
      • 2012-04-22
      • 2012-01-31
      • 1970-01-01
      • 2018-10-09
      相关资源
      最近更新 更多