C ++ - один локальный экземпляр класса для всей продолжительности программы - PullRequest
5 голосов
/ 03 июня 2011

Я работаю над небольшим игровым движком на C ++ и решил сделать все это OOPily (интенсивное использование классов). Он предназначен (теоретически) кроссплатформенным, поэтому у меня есть класс 'Engine',экземпляр которого создается с помощью «Модуля ОС», то есть WinMain для Windows (платформа, для которой я сначала его разрабатываю).

У меня есть три основных вопроса:

  1. Считается ли плохой практикой создание класса, который будет создаваться только один раз во всем приложении? Возможно, потому, что использование некоторого снижения производительности или дополнительных издержек, связанных с использованием класса, скорее всегочем набор функций?

  2. Я планировал, что WinMain создаст экземпляр Engine в качестве локальной переменной.Класс Engine будет довольно большим и будет содержать классы для рендеринга, синтаксического анализа скриптов, файловой системы и т. Д. По сути, весь игровой движок, кроме кода, специфичного для ОС, будет содержаться в классе Engine в некоторой форме (возможно, в качестве примерадругого класса.) Является ли создание локального экземпляра моего очень большого класса Engine в функции WinMain плохой идеей?Является ли создание локального экземпляра плохой идеей, когда класс будет создан при запуске программы и закончится при завершении программы?Может быть, новый будет лучше?

  3. Мой план (и / ва) разделить двигатель на «модули», каждый из которых представленпо классу.Класс Engine будет содержать экземпляр почти всех других модулей, таких как, как упоминалось выше, рендеринг, взаимодействие с файловой системой и т. Д. Использование классов в качестве контейнеров для огромных модулей - плохая идея с некоторой точки зрения (производительность, дизайн,удобочитаемость?)

Спасибо за любую помощь:)

Ответы [ 4 ]

4 голосов
/ 03 июня 2011

Игровые движки не являются первыми кандидатами на кроссплатформенность, поскольку они обычно включают эффективное взаимодействие с низкоуровневыми API (которые не являются кроссплатформенными).

Размер класса зависит от членапеременные, которые он содержит, а не количество функций, которые он реализует.

Пространство стека обычно мало (http://msdn.microsoft.com/en-us/library/ms686774%28v=vs.85%29.aspx), в то время как куча теоретически так же велика, как доступная RAM. Итак, если у вас есть что-то действительно большое,сохраните его в куче (с новым).

«Экран-заставка»: не выполняйте всю работу в начале программы. Пользователи ненавидят ее, когда запускают программу, и на экране ничего не отображается, потому чтоваша программа занята инициализацией чего-то ... Поиск ленивых экземпляров, в основном не делайте вещей, которые могут ждать и всегда показывать что-то на экране.

Что касается конкретных ответов: 1. Нет, если нет виртуальных функций,не должно быть никаких проблем с производительностью. 2. См. «Экран-заставка» и «Ограниченное пространство в стеке» выше. 3. Модульность, как правило, хорошая, простоМы уверены, что каждый класс представляет / представляет одну «вещь».Но не так много классов, вы начинаете забывать их имена и цель:)

2 голосов
/ 03 июня 2011

Считается ли плохой практикой создать класс, который только собирается быть создан один раз во всем приложение? Возможно, потому что есть какой-то производительности ударил или добавил накладные расходы, понесенные при использовании класса а не куча функций?

Совсем нет. Это в основном потому, что ваш класс Application может выполнять такие вещи, как наследование и инкапсуляция Нет снижения производительности или дополнительных затрат.

Я планировал иметь WinMain создать экземпляр Engine как локальная переменная. Класс двигателя будет быть довольно большим, содержащим классы для рендеринга, разбора скрипта, файла системные вещи и т. д. В основном, весь игровой движок, кроме ОС конкретный код, будет содержаться в Класс двигателя в той или иной форме (возможно, как пример другого класс.) Создает локальный экземпляр моего очень большого класса двигателя в функция WinMain плохая идея? Является создание локального экземпляра плохая идея когда класс будет создан, когда программа начинается и заканчивается, когда программа заканчивается? Может быть, новый будет лучше?

Нет, это в значительной степени так и должно быть. Зачем беспокоиться о выделении кучи? Вы хотите автоматическое уничтожение семантики. Если ваш класс не имеет очень большой размер, сотни КБ или более, в этом случае распределение кучи на основе RAII более разумно, так как объем стека ограничен. То есть физический статический размер для каждого экземпляра, о котором сообщает sizeof (), не включая динамические выделения.

Мой план (я / ва) разделить двигатель до «модулей», каждый из которых представлены классом. Двигатель класс будет содержать экземпляр почти все остальные модули, вроде как упомянутое выше, рендеринг, файл Системное взаимодействие и т. д. Используется классы как контейнеры для огромных модулей плохая идея с некоторой точки зрения (производительность, дизайн, читабельность?)

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

Я бы порекомендовал использовать наследование во время выполнения для всех зависящих от платформы и, предпочтительно, динамически загружать их во время выполнения (используя класс OS для выполнения динамической загрузки). Это обеспечивает надежную абстракцию во время компиляции и обеспечивает более эффективную компиляцию.

1 голос
/ 03 июня 2011
  1. Нет, это не считается плохим стилем. На самом деле я не знаю ни одного фреймворка для приложений, который бы работал без него, и известный шаблон Singleton в основном связан с одной и той же темой (но, разумеется, другой)

  2. Я не могу представить, что ваш класс на самом деле такой большой. Если это так, сделайте это в куче. Тем не менее, есть вероятность, что фактическое содержимое этого класса все равно будет в куче (я предполагаю, что вы будете использовать существующие классы контейнеров, которые будут динамически распределяться из 99 из 100; это относится к контейнерам STL как хорошо)

  3. Какая разница, поместите ли вы их в сегмент данных, как auto в стек или члены класса? Я думаю, что класс подчеркивает модульность и может позволить вам делать вещи проще (например, модульное тестирование, или повторное использование движка для сетевой версии и т. Д. И т. Д.)

1 голос
/ 03 июня 2011
  1. Нет, рекомендуется делать все, что делает ваш дизайн чище и удобнее в обслуживании.
  2. Нет, следует по возможности избегать прямого использования freestore (т. Е. Не использовать new, если это не необходимо)
  3. См. # 1
...