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

pet*_*ica 1 c++ virtual-functions linearization c++11

我有这个,也许有点复杂的类层次结构:

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;
};
Run Code Online (Sandbox Code Playgroud)

现在的问题是虽然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()
Run Code Online (Sandbox Code Playgroud)

在我看来似乎BS不知道meth()通过BS-> BCA-> BCS-> T4-> BT4-> BI4链看不到重载方法.
但为什么?该方法显而易见,C++使用的C3线性化算法应该能够非常清楚地找到它.

Bri*_*ian 5

语言规则不允许.虚函数只能通过派生类中具有相同名称和参数的函数声明来覆盖.既然BI4不是派生的BS,BI4::meth也不能覆盖BS::meth.如果一个类从两个继承(直接或间接)BSBI4,那么它继承2个函数调用meth:一个来自BS,仍然抽象和不被重写时,一个来自BI4.