我正在学习多重继承和钻石问题,当我从最终派生类中调用函数时,Visual Studio告诉我该调用是不明确的:
struct A
{
virtual void aFunction() { cout << "I am A\n"; }
};
struct B : A {};
struct C : A {};
struct D : B, C {};
int main()
{
D DObj;
DObj.aFunction(); // This is an ambiguous call
}
我理解如果在B和C类中覆盖了基类函数,则调用将产生歧义,但是在B和C中的“aFunction()”不是相同的吗?
此外,使B和C虚拟继承A会使错误消失。但是,我对继承时关键字“virtual”的理解是它可以防止更深层次的“派生类”从上面继承多个Base的副本 。在继承中,可以继承多个成员变量的副本,但只能继承一个具有相同名称的函数的副本。因此,例如,我可以有5个Derived类,每个类都从Base派生,然后MostDerivedClass从所有5个Derived类继承,在MostDerivedClass中,我将拥有5个Base类“成员变量”的副本,但只有一个具有相同名称的函数的副本。
换句话说,继承时的“虚拟”关键字应防止多个Base“成员变量”副本。我不明白为什么在这种情况下它会消除对含糊不清的函数调用。
编辑:谢谢,现在我慢慢理解了。对于我来说,很难想象D中的“A的两个副本”,因为A是空(没有大小)。但是我记得,C ++永远不会创建空类,在我的设置中,例如,空类的大小为1。然后我能够想象D中有“A的两个副本”,现在开始有意义了。
this
指针。如果您将从 A 派生的类声明为 virtual,则只会有一个 A,没有歧义。struct B : virtual A {};
和struct C : virtual A {};
。 - WaxratA
有一个成员变量,而aFunction
将其打印出来。 - M.M