这个函数调用真的很模糊吗?

Zeb*_*ish 4 c++ polymorphism virtual inheritance

我正在学习多重继承和钻石问题,当我从最派生的类中调用函数时,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
}
Run Code Online (Sandbox Code Playgroud)

我理解如果我在B和C类中重写了基类函数,那么调用将是不明确的,但在B和C中不是"aFunction()"相同吗?

此外,使B和C从A继承实际上会使错误消失.但是我在继承时对关键字"虚拟"的理解,即(Derived:virtual Base),是因为它阻止了链中更多的"派生类"继承链上的多个副本.在继承中,可以继承成员变量的多个副本,但只能复制具有相同名称的函数的一个副本.因此,例如,我可以有5个派生类,每个派生自Base,然后是从所有5个派生类继承的MostDerivedClass,在MostDerivedClass中,我将有5个副本的基类"成员变量",但只有一个函数的副本同名.

换句话说,继承的"虚拟"关键字应该防止多个Base"成员变量"副本.我不明白为什么在这种情况下它会清除一个模糊的函数调用.

编辑:谢谢,它正在慢慢沉入.我不可能想象D中的A"两份",因为A是空的(没有大小).但后来我记得C++从不创建空类,在我的设置上,例如一个空类的大小为1.然后我能够想象D中的A的"两个副本",现在它开始变得有意义了.

Chr*_*odd 5

调用是不明确的,因为有两个可能的A基础对象可以作为this调用的参数传递.即使它是最终被调用的相同的物理函数,并且该函数完全忽略了它的this参数,但是它们中的两个使得它变得模糊不清.

使用virtual继承意味着只有一个A基础对象,因此调用不会是模糊的.