Циркулярная зависимость между классами и их членами

Это C ++. У меня есть основной класс:

#include <QObject>

#include "Logger.h"#include "PluginManager.h"
class Main : QObject
{
Main();
~Main();
Logger &getLogger();

signals:
// Some signals

public slots:
// Some slots
};

И теперь у меня есть класс PluginManager.

Конструктор:

PluginManager( QObject *parent = 0 );

И я строю это в главном классе так:

pluginManager = new PluginManager(this);

Теперь проблема: класс сервера должен создать PluginManager (очевидно), а PluginManager должен получить регистратор из класса сервера а также все плагины тоже!

parent()->getLogger(); // This doesn't work (PluginManager)

Ошибка: у класса QObject нет члена с именем getLogger

Должен ли я создать класс и извлечь его из всех классов?
Пожалуйста, приведите любой пример, который может быть полезен.

Заранее спасибо.

2

Решение

Чтобы столкнуться с зависимостями времени компиляции, есть два метода:

  1. Форвард объявите классы, которые вам нужны.
  2. Используйте интерфейс, чтобы разорвать циклическую зависимость.

Форвардные декларации

В вашем PluginManager.h файл, который вы просто пишете

class Main;

в верхней части файла, чтобы переслать объявить Main, Затем вы объявляете конструктор PluginManager как

PluginManager( Main * parent );

В файле реализации PluginManager вам нужно включить заголовок, который определяет Main класс тогда.

Интерфейсы

Второй вариант использует интерфейс, позволяющий полностью избежать циклической зависимости. Это работает так:

class MainInterface : public QObject
{
Q_OBJECT
public:
MainInterface( QObject * parent ) : QObject(parent) {}
virtual ~MainInterface() {}
virtual void someFunc1() = 0;
virtual void someFunc2() = 0;
// ...
};

class PluginManager : public QObject
{
Q_OBJECT
public:
PluginManager( MainInterface * parent = 0 )
: QObject(parent) { /* ... */ }
// ... other functions ...
};

class Main : public MainInterface
{
public:
Main( QObject * parent = 0 )
: MainInterface(parent) {}
virtual void someFunc1();
virtual void someFunc2();
// ...
};

Граф зависимостей теперь выглядит так

MainInterface                          PluginManager
A       A              instead of        A  |
|       |                                |  V
Main   PluginManager                       Main

Твой выбор

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

1

Другие решения

Что касается ошибки «класс QObject» не имеет члена с именем «getLogger» », то она не имеет ничего общего с циклической зависимостью.

PluginManager( QObject *parent = 0 )

Тип родителя — QObject *, в котором нет члена getLogger (), который является членом класса Main.

0

Изменяется ли часть регистратора в приложении?

Если нет, то при создании PluginManager вы должны также инициализировать регистратор, передавая параметр сложения, удаляя более позднюю зависимость менеджера плагинов от сервера

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector