我有一个像这样的菱形多重继承方案:
A
/ \
B C
\ /
D
公用父项A定义了虚函数fn()。
B和C都可以定义
fn()
吗?如果是,那么下一个问题是-D是否可以毫无歧义地访问B和C的fn()?我假设有一些语法。
D可能会在不特别了解B和C是谁的情况下这样做吗? B和C可以被其他一些类替代,我希望D中的代码通用。
我想做的是让D以某种方式枚举其祖先拥有的fn()的所有实例。这是否有可能以其他方式实现虚拟功能?
最佳答案
除非您再次用fn
覆盖D
,否则不可能。因为D对象中没有最终的替代程序,所以C
和B
都替代A::fn
。您有几种选择:
C::fn
或B::fn
。然后,仍然覆盖A::fn
的那个将具有最终的覆盖器。 A::fn
以及fn
和C
中的B
覆盖。 例如,以下结果导致编译时错误:
#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指针调用函数,您会得到不同的行为。 Herb Sutter的Multiple Inheritance Part III描述了一种很好的方法。它可以帮助您决定设计。
关于c++ - 多重继承+虚拟函数困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/616380/