我有遗传问题。 说我有4节课: 基类A, B级继承A, C级继承A, BC类继承B和C
class A
{
public:
void test()
{
}
};
class B :public A
{
};
class C :public A
{
};
class BC :public B,public C
{
};
int main()
{
BC a;
a.test();
}
结果:
In function ‘int main()’:
error: request for member ‘test’ is ambiguous
note: candidates are: void A::test()
note: void A::test()
我该如何解决这个问题? 这甚至可能吗? 我想要的是BC中所有三个类的单个实例。
问候, Thalhammer
答案 0 :(得分:1)
请注意section 25 on C++ FAQ,注意question 25.8。
如果你希望BC类只从类A派生一次,你应该声明类B和C从A获得虚拟继承:
class A {};
class B : public virtual A {};
class C : public virtual A {};
class BC : public B, public C {};
答案 1 :(得分:0)
对象a
具有两个类型A
的子对象,其中一个包含在其B
基础子对象中,另一个包含在其C
中基础子对象。要选择要调用的那个,请添加中间演员:
BC a;
static_cast<B &>(a).test();
static_cast<C &>(a).test();
答案 2 :(得分:0)
您刚刚发现The Diamond Problem:
简而言之,非虚拟继承意味着为从类继承的每个类创建唯一的基类子对象。 B
和C
都继承自A
,这意味着它们都包含一个单独的A
子对象。当BC
最终继承自B
和C
时,它将共有四个子对象:B::A
,C::A
,B
和{{ 1}}。
调用C
会导致成员BC::test
的名称查找。因为test
有两个BC
子对象,结果是一个模糊的调用,因为这两个函数都是可行的。
虚拟继承意味着将在每个派生类之间共享单个基类子对象。虚拟基类是几乎从中继承的类。使用A
说明符来完成这项工作:
virtual
既然struct A { };
struct B : virtual A { };
struct C : virtual A { };
struct BC : B, C { };
只有一个BC
子对象,对A
的调用将是明确的,因为编译器清楚BC::test
只存在于一个test
。