我学习的多重继承和钻石的问题,当我做一个函数调用从最派生类的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继承了一个几乎让错误消失。但是,当我们继承关键字“虚拟”时,我理解的是它(派生:虚拟基础),它阻止了一个“更多的派生类”沿着链的下游继承多个副本。在继承中,成员变量的多个副本可以被继承,但只有一个具有相同名称的函数副本。因此,例如,我可以在MostDerivedClass 5个派生类分别从基地派生,然后MostDerivedClass从所有5个派生类继承,我将有基地班“的成员变量”的5个人副本,但只有一个功能的副本同名。
因此,换句话说,对于继承“虚拟”关键字应该防止多个基地“成员变量”副本。我不明白为什么它会在这种情况下清除模糊的函数调用。
编辑:谢谢你,它在慢慢下沉这是不可能的,我想象中的d“一分式两份” A,因为A是空的(大小)。但后来我记得C++从不创建空类,例如在我的设置中,空类的大小为1.然后我可以想象D中的A的“两个副本”,现在开始有意义。
我认为,如果没有虚拟,你有功能的2个相同的副本(虽然这仍然是我要学习自己) –
是的,这是正确的。 D包含两个A实例。编译器不知道是否要调用D :: B :: A :: aFunction或D :: C :: A :: aFunction。尽管在任何情况下调用的函数都是相同的,但不同的调用会得到不同的this指针。如果你从A虚拟出来,那么你将只有一个A而且没有歧义。 'struct B:virtual A {};'和'struct C:virtual A {};'。 – Waxrat
(为了证明这不是Visual C++编译器的问题),GCC 5.1给出了[同样的错误](http:// ideone。com/9QYJwy) – UnholySheep