为什么不从不同的继承分支覆盖纯虚方法?

Why are pure virtual methods not overridden from a different inheritance branch?

我有这个,可能有点复杂class层次结构:

class BS {
  public:
    virtual void meth()=0;
};

class BCA : public virtual BS {
};

class BSS : public virtual BS {
};

class BCS : public virtual BCA, public virtual BSS {
};

class BI4 {
  public:
    void meth() {};
};

class BT4 : public virtual BI4, public virtual BSS {
};

class T4 : public virtual BCS, public virtual BT4 {
};

int main() {
  T4 t4;
};

现在的问题是,尽管 void meth() 在继承图中可用,尽管这段代码无法编译:

$ g++ -c t.cc -std=c++11
t.cc: In function ‘int main()’:
t.cc:27:6: error: cannot declare variable ‘t4’ to be of abstract type ‘T4’
   T4 t4;
      ^
t.cc:23:7: note:   because the following virtual functions are pure within ‘T4’:
 class T4 : public virtual BCS, public virtual BT4 {
       ^
t.cc:3:18: note:        virtual void BS::meth()
     virtual void meth()=0;
                  ^
t.cc:3:18: note:        virtual void BS::meth()

在我看来,好像 BS 无法通过 BS->BCA->BCS->T4->BT4->BI4 链看到重载的 meth() 方法。
但为什么?方法一目了然,C++用的C3线性化算法应该能很清楚的找到。

BI4 不直接或间接继承自 BS,因此它的方法 BI4::meth() 完全不相关,不能覆盖 BS::meth().

您只能覆盖基础 类 的方法,而不能覆盖 "sibling" 或 "uncle" 类.

的方法

语言规则不允许。虚函数只能通过在派生 class 中声明具有相同名称和参数的函数来覆盖。由于 BI4 不是从 BS 派生的,因此 BI4::meth 无法覆盖 BS::meth。如果 class 从 BSBI4 继承(直接或间接),那么它会继承 两个 称为 meth 的函数:一个来自 BS,仍然抽象且未被覆盖,其中一个来自 BI4.

主要有两个方面:

  • 给定的 class 只能覆盖其基础 classes 的成员函数。
    由于您的 BI4 class 没有 BS 作为基础 class,它无法覆盖 BS.
  • 的任何内容
  • 可以继承在虚基 class 中定义的纯虚函数的实现,就像在 Java 中一样,但是 class 提供该实现本身也必须具有该虚拟基础 class.

示例:

struct Base
{
    virtual void foo() = 0;
};

#ifdef GOOD
    struct Impl_foo: virtual Base
    {
        void foo() override {}
    };
#else
    struct Impl_foo
    {
        virtual void foo() {}
    };
#endif

struct Abstract_derived: virtual Base
{};

struct Derived
    : Abstract_derived
    , Impl_foo      // Java-like implementation inheritance.
                    // In C++ called "by dominance".
{};

auto main()
    -> int
{
    Derived o;
    o.foo();
}

没有定义 GOOD 宏符号,此代码无法编译。