The Shroom Ответов: 1

Как решить циклическую зависимость?


Моя проблема в том, что у меня есть global_variables.ч файл, который должен знать о файлах :
- Отладчика.ч
- Окна.ч
- Входные.ч

Моя проблема заключается в этом вводе.h должен знать о Window.h, и должен использовать несколько его функций, и поэтому он также нуждается в файле global_variables.h, И теперь я столкнулся с циклической зависимостью.

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

Но, поскольку я новичок, я не думал об этой проблеме, с которой я сейчас сталкиваюсь. :/

Вот несколько примеров кода :

Global_Variables.ч :
#pragma once

#include "Debugger.h"
#include "Window.h"
#include "Input.h"

// The name of the game the engine is currently running.
static const std::string GAME_NAME = "SwEngine Testing";

// The debugging/logging and also error handling component of the engine.
static Debugger global_debugger;

// The window/rendering/graphics component of the engine.
static Window global_window;

// The input component of the engine.
// Handles events such as window closing, keyboard pressing and mouse moving.
static Input global_input;


А входной класс создается заново, имеет только деструктор и конструктор, а также некоторые комментарии.

Итак, как я должен решить эту проблему? :)

Что я уже пробовал:

Я пробовал гуглить, но на самом деле не нашел никаких хороших ответов о том, как решить эту проблему.
Так что я еще ничего толком не пробовал.

Philippe Mori

Global_variables. h-плохая идея. Это вызовет много перекомпиляции, так как будет использоваться везде и зависит от многих файлов. Каждая переменная должна быть объявлена в соответствующем заголовочном файле, чтобы, скажем, изменение в отладчике повлияло только на исходные файлы, которые зависят от отладчика.

Philippe Mori

Прямые объявления и соответствующее разделение файлов могут помочь избежать циклов.

1 Ответов

Рейтинг:
2

Jeremy Falcon

Есть несколько способов сделать это. Традиционный олдскульный, наиболее совместимый способ-использовать то, что называется Include guard.

включить охрану-Википедия, свободная энциклопедия[^]

В принципе, если окно.h должен убедиться, что Input.h и global_variables.h включены, но так же как и другие области программы, тогда использование guards гарантирует, что компиляция обрабатывает только то, что находится в include один раз.

Кроме того, используя #pragma once во всех ваших заголовках есть другой путь. Не только в главном файле. Но это специфично для некоторых компиляторов, таких как Visual Studio, поэтому не рекомендуется, если у вас нет желания когда-либо переключать компиляторы.


The Shroom

(Не уверен, что это вообще ответ на ответ, но надеюсь, что это так... лол)
Я действительно использую #pragma один раз во всех своих заголовках, но у меня все еще есть циклические зависимости?

Теперь я не уверен, является ли это циклической ошибкой, связанной с зависимостями, или нет...
Есть ли какой-нибудь способ отредактировать мой вопрос, чтобы я мог добавить больше кода?

Jeremy Falcon

Тогда вы обнаружите, что нет никакого способа исправить эту ошибку, не изменив дизайн вашего приложения. Global_Variables.h действует здесь больше как основной включаемый файл, и это нормально. Просто посмотрите на это с широкой и узкой точки зрения и перепроектируйте свое приложение... Основные части приложения & gt; глобальный & gt; отладчик, окно, ввод.

The Shroom

Решил вместо этого кататься с Синглетами, похоже, пока работает. :)

Philippe Mori

Глобальные переменные и синглтон обычно считаются плохой практикой... Для больших приложений это может вызвать у вас много проблем. Код будет написан при условии, что он всегда может использовать глобальное состояние, которое в какой-то момент может больше не иметь места (многопоточность, многопользовательский режим или просто необходимость в независимом объекте в определенном контексте).
Таким образом, лучше понять ограничения, прежде чем начинать большой проект...
Обычно вместо этого лучше всего использовать какую-то форму инъекции депеденций.

The Shroom

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

Philippe Mori

Бедняга Ди был бы что ты творишь Debugger, Window и Input объекты сначала запускаются, а затем передаются соответствующим конструкторам (или функциям), которые в них нуждаются.
В реальной жизни иногда вы идете на некоторый компромисс, но всегда предпочтительнее ограничить код, который непосредственно использует глобальное состояние.
Еще одна причина, по которой вы, возможно, не захотите иметь слишком много глобального состояния, заключается в том, что если вы создадите другую игру, то, возможно, захотите использовать другую реализацию для Input модуль...

The Shroom

О, я вижу, я думаю, что это тоже сработает.