我有这个,也许是一个复杂的类层次结构:
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线性化算法应该能够非常清楚地找到它。
答案 0 :(得分:5)
语言规则不允许。虚函数只能通过派生类中具有相同名称和参数的函数声明来覆盖。由于BI4
不是来自BS
,BI4::meth
无法覆盖BS::meth
。如果某个类({1}}和BS
继承(直接或间接),则它继承了名为BI4
的两个函数:一个来自meth
,仍然是抽象的而不是被覆盖的,而且来自BS
。
答案 1 :(得分:2)
BI4
不会直接或间接地从BS
继承,因此其方法BI4::meth()
完全不相关,无法覆盖BS::meth()
。
您只能覆盖基类中的方法,而不能覆盖“兄弟”或“叔叔”类中的方法。
答案 2 :(得分:2)
主要有两个方面:
BI4
类没有BS
作为基类,因此无法覆盖BS
中的任何内容。示例:
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
宏符号,则此代码不会编译。