Code -
#include<iostream>
using namespace std;
class P {
public:
void print() { cout <<" Inside P"; }
};
class Q : public P {
public:
void print() { cout <<" Inside Q"; }
};
class Q2: public P {
public:
void print2() { cout <<" Inside Q2"; }
};
class R: public Q2, public Q { };
int main(void)
{
R r;
r.print(); // error: request for member ‘print’ is ambiguous
return 0;
}
预期行为:在main的第三行没有二义性调用。
实际行为:main
第三行有歧义调用原理:我期望类Q隐藏类P的print()函数。当Q2与R或Q(甚至P?)具有相同的函数名称时,我期望出现歧义调用错误。但我故意将Q2中的函数名称改为"print2"以避免此错误。当我删除'Q2'作为r的父类时,此错误会消失。这是因为'Q2'从'P'继承了'print'吗?
注意:我知道类似的问题已经被问到关于常规继承的数据隐藏和在多个类继承的情况下的模糊调用,但这种情况是两种情况的混合,我没有找到任何具体的答案。
我期望类Q隐藏类p的print()函数
这与Q
隐藏超类的print()
无关。
Q2
继承P
,因此继承print()
。
class R: public Q2, public Q { };
print()
同时继承自Q2和q。它们是否相同或不同的方法是无关紧要的。关键是print()
方法R.print()
解析到哪一个是不明确的。
将期望出现歧义调用错误。
但确实如此。它继承了它
这是一个非常典型的带有多重继承的c++菱形问题。
你得到的是当R调用打印函数时,他不知道从哪个打印调用。
你可以通过帮助R类对象指定你想调用哪个打印来解决这个问题。
下面的修改可以说明这一点。
#include<iostream>
using namespace std;
class P {
public:
void print() { cout <<" Inside Pn"; }
};
class Q : public P {
public:
void print() { cout <<" Inside Qn"; }
};
class Q2: public P {
public:
void print2() { cout <<" Inside Q2n"; }
};
class R: public Q2, public Q { };
int main(void)
{
R r;
r.Q::print();
r.Q2::print();
// r.P::print(); ambiguous base call.
// r.print(); ambiguous member
return 0;
}