继承问题“模棱两可的要求”

时间:2014-08-22 22:52:12

标签: c++ ambiguous

我有遗传问题。 说我有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

3 个答案:

答案 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

简而言之,非虚拟继承意味着为从类继承的每个类创建唯一的基类子对象。 BC都继承自A,这意味着它们都包含一个单独的A子对象。当BC最终继承自BC时,它将共有四个子对象:B::AC::AB和{{ 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