为什么纯虚拟方法没有从不同的继承分支重写
Why are pure virtual methods not overridden from a different inheritance branch?
我有这个,也许有点复杂的类层次结构:
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
。如果一个类(直接或间接)继承自BS
和BI4
,那么它继承了两个称为meth
的函数:一个来自BS
,仍然是抽象的,没有被覆盖,另一个来自BI4
。
主要有两个方面:
- 给定类只能重写其基类中的成员函数。
由于您的BI4
类没有BS
作为基类,因此它无法覆盖BS
中的任何内容。 - 可以在实现中继承在虚拟基类中定义的纯虚函数,就像在 Java 中一样,但提供该实现的类本身也必须具有该虚拟基类。
例:
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
宏符号,则此代码无法编译。
BI4
不会直接或间接地从BS
继承,因此其方法BI4::meth()
完全不相关,不能覆盖BS::meth()
。
只能重写基类中的方法,而不能重写"同级"或"叔类"中的方法。
相关文章:
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- IPC使用多个管道和分支进程来运行Python程序
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 如何删除peer if else分支中的冗长句子
- 公共与私人继承
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 如何创建从同一类继承的不同对象的向量
- 如何从另一个文件继承私有成员变量和公共函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 带有继承的C++工厂
- 我应该避免多重实现继承吗
- 如何防止子分支进程继承CPU亲和性
- 为什么纯虚拟方法没有从不同的继承分支重写