C ++中的多重继承问题:
它看起来像钻石问题,但事实并非如此。它不能通过添加虚拟继承来解决。
struct A {
virtual void f() { cout << "A::f()" << endl; };
};
struct B : public virtual A {
void f() { cout << "B::f()" << endl;};
};
struct C : public virtual A {
void f() { cout << "C::f()" << endl;};
};
struct D : B, C { };
int main() {
D d;
B* bp = &d;
A* ap = bp;
D* dp = &d;
ap->f();
dp->f(); // compile error here because D has two candidates f() to override.
// error: request for member f is ambiguous
// error: candidates are: virtual void C::f()
// error: virtual void B::f()
}
我是对的吗?
答案 0 :(得分:4)
它看起来像钻石问题,但事实并非如此。
是的;这是经典的“钻石”图案。也许你的意思是,这个问题不是由钻石的存在引起的?这当然是正确的,所以我想知道为什么你在这个问题中包含了那个红鲱鱼。你会从一个更简单的例子中得到同样的问题:
struct B {
virtual void f() { cout << "B::f()" << endl;};
};
struct C {
virtual void f() { cout << "C::f()" << endl;};
};
struct D : B, C { };
这里编译错误,因为D有两个候选f()要覆盖。
不,错误是因为D
没有覆盖它们,所以函数调用有两个候选者。虚函数在两个直接基类中都被重写,但在派生类中没有,因此没有唯一的最终覆盖。
您需要决定D::f()
应该做什么,并相应地实施。
答案 1 :(得分:0)
错误不在您指定的行中,而是在D
的类定义中。该定义完全不正确,因为虚函数没有唯一的最终覆盖。
答案 2 :(得分:0)
你有两个具有相同签名的函数来自B类和C类,因此成员函数f()
是不明确的(你已经指出过)。
答案 3 :(得分:-1)
也许ap = bp会隐式转换,因此ap-&gt; f()将被识别为B :: f,但dp有两个f()可供选择。
编辑:任何人都可以解释为什么ap-&gt; f()不会抛出错误但是dp-&gt; f()会不会?