Круговые зависимости? [Дубликат]

0

Хорошо, я понимаю форвардные объявления, но в этом случае мне нужно вызвать участников/полей на BOTH, поэтому я не могу использовать это. Я попытался перезаписать декларацию внутри.cpp файла (включив фактический заголовок класса, который мне нужно использовать), но указатель, который я определил в заголовке посредством прямого объявления, был сломан, когда я пытался его использовать.

Как я могу обойти это? Вам нужен код?

  • 0
    Описанная вами взаимозависимость указывает на недостаток дизайна. Пересмотрите свой дизайн и устраните тесную связь между двумя типами.
  • 2
    SSCCE было бы прекрасно ... sscce.org
Показать ещё 5 комментариев
Теги:
dependencies
circular

2 ответа

3
Лучший ответ

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

A.hpp

class B;

class A
{
public:
  int foo(B *b);
  int bar();
};

B.hpp

class A;

class B
{
  A *m_a;
public:
  int foo();
  explicit B(A *a) : m_a(a) {}
};

a.cpp

#include "A.hpp"
#include "B.hpp"

int A::foo(B *b)
{
  return 2 * b->foo();
}

int A::bar()
{
  return 42;
}

B.cpp

#include "A.hpp"
#include "B.hpp"

int B::foo()
{
  return m_a->bar();
}
  • 0
    Я пробовал это, но указатель был недействительным (исключение памяти)
  • 0
    AHH! Вы правы, я неправильно назвал переменную!
0

Если вы единственный, у кого будет доступ к внутренней части кода (например, когда вы делаете проект самостоятельно, самостоятельно или распространяете закрытый.lib/.dll), и вы уверены, что вам нужны ваши классы, чтобы включить себя круговым способом, вы всегда можете использовать абстрактный базовый класс.

class base{};

class A: public base{
   base *bMember;
};

class B: public base{
   base *aMember;
};

Это немного плохой практики, но если вам нужно прямое решение, этого должно быть достаточно. Лучше всего было бы исправить зависимости или использовать отдельные базовые классы.

  • 0
    Даже если он действительно должен был сделать это, почему бы недостаточно пересылать декларации? Я не вижу смысла абстрактного базового класса.
  • 0
    Некоторые старые IDE, как правило, игнорируют предварительные объявления. У меня была такая проблема, когда я давно делал проект с какой-то версией VS.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню