Макет файла / папки для большого проекта C ++ с несколькими уровнями наследования - PullRequest
4 голосов
/ 17 июля 2010

Я нахожусь на стадии планирования относительно большого (10 000+ строк) проекта с несколькими классами (30+) и несколькими уровнями наследования классов (5+).

Что является лучшим (или наиболееобычный) способ размещения моего проекта с точки зрения структуры файлов и папок?

  1. Должен ли я иметь один файл на класс?Должен ли я иметь одну папку для каждой ветви наследования?
  2. Должен ли я иметь папку «include», содержащую мои файлы заголовков, или мои файлы заголовков должны находиться в той же папке, что и мои .cpp / .c файлы?
  3. Я планирую регулярно добавлять больше классов (добавляя больше уровней в дерево наследования).На самом низком уровне дерева реализации, скорее всего, будут относительно не связаны, но все же будут переопределять те же виртуальные функции.Должны ли такие несвязанные реализации находиться в одной папке?

Спасибо,
Advait

Ответы [ 4 ]

5 голосов
/ 17 июля 2010

1) Да. Один файл на класс в большинстве случаев - хорошая идея. Если у вас нет действительно тривиального класса или набора абстрактных интерфейсов, используйте один класс на файл.

2) Попробуйте разделить вещи. Обычно в таком большом проекте у вас есть некоторый код, специфичный для одних частей, другие - общие для многих частей. Те, которые очень ограничены в использовании, просто держите его «локально». Другие, включая dirs.

3) На самом деле не нужно. Обычно лучше держать классы (то есть файлы), которые тесно связаны, близко друг к другу; Я бы постарался сохранить их вместе, если у вас есть что-то вроде общего интерфейса, в ваших глобальных включениях и специфическом наследовании внутри модуля dir.

1 голос
/ 17 июля 2010
  • Должен ли я иметь один файл на класс? Должен ли я иметь одну папку на ветку наследования?

Благодаря индексаторам кода я часто забываю, как и где код на самом деле находится на диске.

Файл для каждого класса для меня не имеет смысла. Особенно в C ++ у меня много маленьких служебных классов.

Обычно: компонент - это каталог. Все компоненты живут под одним корнем. (Это более печальное следствие, что я должен использовать make как цепочку сборки. С лучшими системами сборки, такими как SCons , которые изначально поддерживают рекурсию, это не имеет значения.)

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

  • Должна ли я иметь папку «include», содержащую мои файлы заголовков, или мои файлы заголовков должны находиться в той же папке, что и мои файлы .cpp / .c?

Лично я предпочитаю заголовки в одном каталоге с исходными файлами.

Заметным исключением являются открытые заголовки, которые определяют открытый интерфейс компонента. Те, что я положил в include / compname / sudbirectory: тогда легко увидеть, что изменение, которое я делаю / собираюсь зарегистрировать, повлияет на другие компоненты.

Очевидно, что другим компонентам разрешено включать только заголовки из подкаталога $ ROOT / compname / include / compname /. (Наличие compname / dir в include / make включает директивы include в других файлах, чтобы они выглядели как #include "compname/headername.h", что способствует удобочитаемости и предотвращает конфликты имен заголовков.)

  • Я планирую регулярно добавлять больше классов (добавляя больше уровней в дерево наследования). На самом низком уровне дерева реализации, скорее всего, будут относительно не связаны, но все же будут переопределять те же виртуальные функции. Должны ли такие несвязанные реализации находиться в одной папке?

Наследование редко имеет отношение к физическому расположению файлов.

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

Это приносит еще один важный момент. Сколько людей собирается работать над проектом? На одном человеке проекта вы можете делать почти все, что вы хотите, как вы хотите. В команде из 3+ человек компонент / модуль будет служить естественным контейнером для одного человека, который будет работать над ним независимо. Таким образом, проект формы может не зависеть от того, как выглядит иерархия классов - скорее места кода, над которыми будет работать большинство, должны быть достаточно изолированы друг от друга. И иерархия классов при необходимости должна быть приспособлена для этого: вам следует избегать случаев, когда один человек работает над базовым классом, а другой - над его потомком. Это тот случай, когда можно рассматривать агрегацию вместо наследования.

1 голос
/ 17 июля 2010

1) Это больше похоже на тип Java - но если ваши классы занимают не более 4 строк, возможно, это не очень хорошая идея.Но если в дальнейшем вы захотите расширить уже существующий класс, хорошей идеей будет один файл для каждого класса.

2) Это выбор для вас, как расположить ваши файлы .h и .cpp.Но если много зависимостей должно быть для одного класса, кажется разумным поместить связанные в одном месте.

3) Возможно.Но поместите ваши базовые классы / интерфейсы в центральную часть и извлекайте их из этого.

0 голосов
/ 17 июля 2010

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

Это верно на уровне файлов, и это также верно на уровне папок, но для больших блоков кода.*

Вы также должны знать, что компилятор плохо оптимизирует код между файлами (проблема в компоновщике).Так что, если у вас есть тесно связанные классы, хранение их в одном файле хорошо для производительности.Другое решение, когда возможно сделать их заголовками только классов.

Где хранить заголовки?Если вы предоставляете библиотеку, вам придется поместить их в обычные системные каталоги.Но поскольку заголовки C ++ содержат код, для других случаев лучше всего хранить их в файлах cpp.Это упрощает редактирование hpp и cpp одновременно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...