C ++具有纯虚函数的多继承pproblem

时间:2016-03-13 19:56:20

标签: c++ inheritance

我已经制作了一个最小的例子来复制我看到的更复杂的类层次结构的问题:

#include <string>
#include <iostream>


class A
{
protected:

    virtual
    ~A() = 0;

};

inline
A::~A() {}

class B : public A
{
public:

    virtual
    ~B()
    {
    }

    std::string B_str;
};

class BB : public A
{
public:

    virtual
    ~BB()
    {
    }

    std::string BB_str;
};

class C : public A
{
protected:

    virtual
    ~C()
    {
    }

    virtual
    void Print() const = 0;
};

class D : public B, public BB, public C
{
public:

    virtual
    ~D()
    {
    }
};

class E : public C
{
public:

    void Print() const
    {
        std::cout << "E" << std::endl;
    }
};

class F : public E, public D
{
public:

    void Print_Different() const
    {
        std::cout << "Different to E" << std::endl;
    }

};


int main()
{

    F f_inst;

    return 0;
}

使用g++ --std=c++11 main.cpp进行编译会产生错误:

error: cannot declare variable ‘f_inst’ to be of abstract type ‘F’

    F f_inst;

note:   because the following virtual functions are pure within ‘F’:

    class F : public E, public D
          ^
note:   virtual void C::Print() const

    void Print() const = 0;
         ^

因此编译器认为Print()是纯虚拟的。

但是,我已在Print()中指定class E应该是什么。

所以,我误解了一些继承规则。

我的误解是什么,我该如何纠正这个问题呢?

注意:如果我从: public D删除继承class F,它将被编译。

1 个答案:

答案 0 :(得分:2)

目前,您的F以两种不同的方式来自C。这意味着F对象有两个单独的C个基础,因此有两个C::Print()个实例。

您只能覆盖当前通过E发送的那个。

要解决此问题,您必须采取以下选项之一:

  • 还可以通过实施DD::Print()
  • 覆盖通过F::Print()发送的内容
  • Print非纯粹
  • 使用虚拟继承,以便只有一个C基础。

对于后一种选择,语法调整将是:

class E : virtual public C

class D : public B, public BB, virtual public C

这意味着DE都将与其父级具有相同的C实例,因此覆盖E::Print()会覆盖所有类“下游”的函数那个C

有关更多信息,请查看“钻石继承问题”。另请参阅Multiple inheritance FAQ