Как решить проблему наследования сетки в C ++ - PullRequest
0 голосов
/ 17 января 2019

У меня есть следующий набор классов, которые наследуются друг от друга в виде сетки. На верхнем уровне у меня есть абстрактные классы. И Abstract_Class_B, и Abstract_Class_C наследуются от Abstract_Class_A.

На втором уровне наследования у меня есть точные реализации этих классов.

  1. Impl_Class_A наследуется от Abstract_Class_A.
  2. Impl_Class_B наследуется от Abstract_Class_B и Impl_Class_A.
  3. Impl_Class_C наследуется от Abstract_Class_C и Impl_Class_A.

Когда я компилирую приведенный ниже код, компилятор прекрасно компилируется, если я не объявляю какой-либо класс в коде. Но когда я начинаю объявлять указатель на классы второго уровня, компилятор выдает следующую ошибку:

undefined reference to `VTT for ns3::Impl_Class_B'
undefined reference to `vtable for ns3::Impl_Class_B'

Я использовал virtual для решения типичной проблемы алмазов в наследовании, но я все еще не могу скомпилировать. Имеет смысл, что компилятор запутывается из-за этого способа наследования. Но моя система требует такого дизайна для этих классов. Любое решение, чтобы решить эту проблему?

код:

// Top Level (Level 1)

class Abstract_Class_A
{
};

class Abstract_Class_B: virtual public Abstract_Class_A
{
  public:
  uint8_t type;
};

class Abstract_Class_C: virtual public Abstract_Class_A
{
};

// Second Level (Level 2)
class Impl_Class_A : virtual public Abstract_Class_A
{
  public:
  double angle;
};

class Impl_Class_B: virtual public Abstract_Class_B, Impl_Class_A
{
};

class Impl_Class_C: virtual public Abstract_Class_C, Impl_Class_A
{
};

void test()
{
  Impl_Class_B* test = new Impl_Class_B ();
}

1 Ответ

0 голосов
/ 17 января 2019

Проблема оказалась связана с другими виртуальными функциями внутри исходных классов, которые были в моем коде. Код выше работает без проблем. Во время разработки я столкнулся с другими проблемами, поэтому я отправил ей новый код, который решает все эти проблемы с комментариями, упомянутыми рядом с ними:

// Top Level (Level 1)

class Abstract_Class_A
{
     ~Abstract_Class_A (); // To solve source type is not polymorphic” when trying to use dynamic_cast
};

class Abstract_Class_B: virtual public Abstract_Class_A
{
  public:
  uint8_t type;
};

class Abstract_Class_C: virtual public Abstract_Class_A
{
};

// Second Level (Level 2)
class Impl_Class_A : virtual public Abstract_Class_A
{
  public:
  double angle;
};

class Impl_Class_B: virtual public Abstract_Class_B, virtual public Impl_Class_A // Missing second virtual
{
};

class Impl_Class_C: virtual public Abstract_Class_C, virtual public Impl_Class_A // Missing second virtual
{
};

void test()
{
  Impl_Class_B* test = new Impl_Class_B ();
}

Примечания:

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