C++ 多重继承中何时出现歧义?

C++ 多重继承中何时出现歧义?,c++,C++,多重继承中何时会出现歧义?当您在多个继承路径中复制了基类,并且您试图强制转换到它或调用它的成员函数时 struct A { }; struct B : A { }; struct C : A { }; struct D : B, C { }; // has replicated A as the base class D d; A* a = static_cast<A*>(&d); // oops struct A{}; 结构B:A{}; 结构C:A{}; 结构D:B,C

多重继承中何时会出现歧义?

当您在多个继承路径中复制了基类,并且您试图强制转换到它或调用它的成员函数时

struct A { };
struct B : A { };
struct C : A { };
struct D : B, C { }; // has replicated A as the base class

D d;
A* a = static_cast<A*>(&d); // oops
struct A{};
结构B:A{};
结构C:A{};
结构D:B,C{};//已将复制为基类
D;
A*A=静态演员阵容,尤其是

。要修复此问题,只需使用虚拟继承:

struct Derived1 : virtual public Base{
};
struct Derived2 : virtual public Base{
};

歧义的另一种可能性是:

struct Base1{
  void foo(){
  }
};

struct Base2{
  void foo(){
  }
};

struct Final : public Base1, public Base2{
};

int main(){
  Final f;
  f.foo();
}
再说一次,开玩笑。要修复此问题,请在
Final
中执行以下操作:

struct Final : public Base1, public Base2{
  using Base1::foo;
  // or
  // using Base2::foo;
};

多重继承中模糊性的一个著名例子是所谓的钻石问题

总结: “在具有多重继承和知识组织的面向对象编程语言中,菱形问题是当两个类B和C继承自A,而类D继承自B和C时产生的歧义。如果D中的方法调用A中定义的方法(并且不重写该方法),并且B和C以不同的方式重写了该方法,那么它从哪个类继承:B还是C?”


您可以在此处找到详细信息:

当它使使用的名称不清楚时

class baseX
{
  private:
  void* callA();//will never be ambiguous.
  protected:
  void* callB();
  public:
  void* callC();
}
class baseY
{
  private:
  void* callA();//will never be ambiguous.
  protected:
  void* callB();
  public:
  void* callC();
}
class derived: public baseX, public baseY
{
  void someMethod()
  {
    void* x = baseX::callB();//not ambiguous
    void* y = baseY::callB();//not ambiguous
    void* z = callB();//ambiguose
  }
}
void someFunction(derived& d)
{
  void* x = d.CallC();//ambiguous
}
当同一类别是通过多条路线的基础时,也可能发生歧义:

class Base
{
  public void call();
}
class DerivedX : public Base
{
}
class DerivedY : public Base
{
}
class GrandChild : public DerivedX, public DerivedY //What does call() do?
{
}
这可以通过虚拟基地来解决:

class Base
{
  public void call();
}
class DerivedX : public virtual Base
{
}
class DerivedY : public virtual Base
{
}
class GrandChild : public DerivedX, public DerivedY //only one "Base" class in inheritance, shared between DerivedX and DerivedY
{
}

请再详细一点。也许是个例子?ETC对模棱两可的内容进行解释。您可以有菱形继承,同一基类可以多次继承。或者你可以有多个具有相同名称的公共/受保护成员变量/函数的基,需要明确的资格才能访问。在这里,你需要在发布问题之前做更多的研究。如果问题清晰,那么答案将是这样的,你将对你所寻找的东西有更多的洞察力。
class Base
{
  public void call();
}
class DerivedX : public virtual Base
{
}
class DerivedY : public virtual Base
{
}
class GrandChild : public DerivedX, public DerivedY //only one "Base" class in inheritance, shared between DerivedX and DerivedY
{
}