具有多重继承的模糊基

Ambiguous base with multiple inheritance

本文关键字:模糊 多重继承      更新时间:2023-10-16

我正试图在一个大库中编写类的一些子类。我得到了一个"模糊的基数"错误。下面是该问题的一个可编译示例:

#include <iostream>
// I can't change these because they are in the library:
class InteractorStyle {};
class InteractorStyleCamera : public InteractorStyle {};
class InteractorStyleImage : public InteractorStyle {};
// These are my subclasses (so I can change them):
class PointSelector : public InteractorStyle {};
class PointSelector2D : public InteractorStyleCamera, public PointSelector
{
  // This function has to exist exactly like this (a requirement of the library):
  static PointSelector2D* SafeDownCast(InteractorStyle *o)
  {
    return static_cast<PointSelector2D *>(o);
  } 
};

int main()
{
  return 0;
}

错误是

错误:' InteractorStyle '是' PointSelector2D '的模糊基。

在这种情况下我能做些什么吗?

你的问题是交互器样式被继承了两次-一次是PointSelector2D,一次是InteractorStyleCamera。这意味着在你的类中包含了它的每个成员的两个版本。

查看:

使用多重继承时如何避免死亡之钻?

尝试虚拟继承

您可以通过使用两步强制转换来表面上"修复"它。例如

static_cast<PointSelector2D *>(static_cast<InteractorStyleCamera *>(o));

当然,您必须记住,这"修复"了语法,但并没有修复潜在的结构问题。你的PointSelector2D有两个InteractorStyle基子对象在里面。根据从哪个InteractorStyle基子对象开始,上行路径是不同的。选择正确的道路是非常重要的。我上面写的是InteractorStyleCamera里面的InteractorStyle。对于另一个碱基,正确的上转换应该是

static_cast<PointSelector2D *>(static_cast<PointSelector *>(o));

如果你只是给出一个InteractorStyle *指针,没有关于它指向哪个基的额外信息,那么你不可能用static_cast解决你的问题。没有办法知道该走哪条向上的路。选错了会产生完全没有意义的结果。

正如已经注意到的,dynamic_cast可以在这种情况下提供帮助,但它有额外的要求(多态起始类型)。您的类型不是多态的(至少在您引用的示例中),因此dynamic_cast将不接受它们进行向上转换。

我相信你可以通过使用dynamic_cast而不是static_cast来解决这个问题。dynamic_cast可以在运行时查看对象,以确定指向两个InteractorStyle基类中的哪一个,并从那里将指针向下调整为适当的类型。

您可以通过将InteractorStyle添加到PointSelector2D继承的类中来编译代码(我至少编译了您的示例)。我不知道这是否是一个长期的解决方案。