Подтвердить что ты не робот

Неоднозначная база с множественным наследованием

Я пытаюсь написать некоторые подклассы классов в большой библиотеке. Я получаю ошибку "неоднозначной базы". Вот компилируемый пример проблемы:

#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;
}

Ошибка

error: "InteractorStyle - это двусмысленная база" PointSelector2D ".

Есть ли что-нибудь, что я могу сделать в этом случае?

4b9b3361

Ответ 1

Ваша проблема в том, что стиль Interactor наследуется дважды - один раз PointSelector2D и один раз InteractorStyleCamera. Это означает, что у вас есть 2 версии каждого члена, содержащиеся в вашем классе.

Отъезд:

Как я могу избежать Diamond of Death при использовании множественного наследования?

И попробуйте виртуальное наследование.

Ответ 2

Вы можете поверхностно "исправить" его, используя двухэтапный отбор. Например

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

Конечно, вы должны иметь в виду, что это "исправляет" синтаксис, но не устраняет основную структурную проблему. Ваш PointSelector2D имеет два субъекта базы данных InteractorStyle. В зависимости от того, с каких начальных подобъектов InteractorStyle вы запускаете, путь повышения скорости отличается. И очень важно принять правильный путь. То, что я написал выше, для InteractorStyle внутри InteractorStyleCamera. Для другой базы правильный upcast будет

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

Если вам задан указатель InteractorStyle * без дополнительной информации о том, к какой базе он указывает, то вы не можете решить свою проблему с помощью static_cast. Там нет способа узнать, какой путь upcast принять. Взятие неправильного приведет к совершенно бессмысленному результату.

Как уже отмечалось, dynamic_cast может помочь в этой ситуации, но имеет дополнительные требования (полиморфный стартовый тип). Ваши типы не являются полиморфными (по крайней мере, в приведенном ниже примере), поэтому dynamic_cast не будет принимать их для повышения.

Ответ 3

Я считаю, что вы можете исправить это, используя dynamic_cast вместо static_cast. dynamic_cast может посмотреть объект во время выполнения, чтобы определить, какой из двух базовых классов InteractorStyle указывается, и оттуда можно настроить указатель до соответствующего типа.

Ответ 4

Вы можете получить свой код для компиляции (я получил ваш пример для компиляции, по крайней мере), добавив InteractorStyle к классам, которые наследует PointSelector2D. Является ли это долгосрочным решением, я не знаю.