我有一个像这样的菱形多重继承场景:
A
/ \
B C
\ /
D
共同的父节点 A 定义了一个虚函数 fn()。
B和C都可以定义fn()
吗?
如果是,那么下一个问题是 - D 可以无歧义地访问 B 和 C 的 fn() 吗?我假设这有一些语法..
D 是否有可能在不明确知道 B 和 C 是谁的情况下这样做? B 和 C 可以被其他一些类替换,我希望 D 中的代码是通用的。
我想要做的是让 D 以某种方式枚举它在其祖先中拥有的所有 fn() 实例。这是否可能以其他方式表示虚函数?
最佳答案
除非您在 D
中再次覆盖 fn
,否则这是不可能的。因为在 D 对象中没有最终覆盖器:C
和 B
都覆盖了 A::fn
。您有多种选择:
- 删除
C::fn
或B::fn
。然后,仍然覆盖A::fn
的那个拥有最终的覆盖器。 - 在 D 中放置一个最终覆盖器。然后,该覆盖器覆盖
A::fn
以及C
和B 中的
。fn
例如以下导致编译时错误:
#include <iostream>
class A {
public:
virtual void fn() { }
};
class B : public virtual A {
public:
virtual void fn() { }
};
class C : public virtual A {
public:
virtual void fn() { }
};
// does not override fn!!
class D : public B, public C {
public:
virtual void doit() {
B::fn();
C::fn();
}
};
int main(int argc, char **argv) {
D d;
d.doit();
return 0;
}
但是,您可以从 C 和 B 中的 A 派生非虚拟,但是您不再有菱形继承(钻石问题)。也就是说,A 中的每个数据成员在 B 和 C 中出现两次,因为在 D 对象中有两个 A 基类子对象。我建议您重新考虑该设计。尝试消除需要虚拟继承的双重对象。它经常导致这种冲突的情况。
与此非常相似的情况是您想要覆盖特定函数。想象一下,你在 B 和 C 中有一个同名的虚函数(现在没有共同的基 A)。在 D 中,您希望覆盖每个函数,但为每个函数赋予不同的行为。根据您是使用 B 指针还是 C 指针调用函数,您会有不同的行为。 Multiple Inheritance Part III Herb Sutter 的作者描述了一个很好的方法。它可能会帮助您决定您的设计。
关于c++ - 多重继承+虚函数困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/616380/