Практика наличия “Общего” заголовка

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

Например, если несколько типов могут иметь a Color, который является перечислением, Вы хотели бы сделать это доступным. Некоторые люди сказали бы для помещения его в класс, что это "подходит лучше всего с", но это может создать проблемы зависимости от заголовка.

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

10
задан AnonJr 21 January 2010 в 17:25
поделиться

6 ответов

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

Например, вот два отрывка из моего Common.h:

typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned char uint08;
typedef signed char int08;
typedef unsigned short uint16;
typedef signed short int16;
typedef unsigned int uint32;
typedef signed int int32;
typedef unsigned long long uint64;
typedef signed long long int64;
typedef const char cchar;
typedef const bool cbool;
typedef char Byte;


#ifdef ASSERT
/* Re-defining assert */
#undef ASSERT
#endif

#ifdef DEBUG
#ifndef ASSERTIONS
#define ASSERTIONS
#endif
#endif

#define ASSERT_ALWAYS(Expression)   if (!(Expression)) FatalError(ErrorInfo("Assertion Failure", #Expression, FUNCTION_NAME, __FILE__, __LINE__))

#ifdef ASSERTIONS
#ifdef DEBUG
#define ASSERT(Expression)   ASSERT_ALWAYS(Expression)
#else
#define ASSERT(Expression)   if (!(Expression)) ErrorLog("[Release Assertions]: The following assertion failed: " # Expression)
#endif
#else
#define ASSERT(Expression)
#endif
9
ответ дан 3 December 2019 в 17:20
поделиться

Лично я не поклонник.

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

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

Есть случай, когда константа или тип широко используется или когда константа или тип совместно используется всеми модулями.

4
ответ дан 3 December 2019 в 17:20
поделиться

Общий заголовок в порядке, если над вашим проектом работают всего несколько человек. Как только у вас будет более 20 человек, которые будут редактировать этот файл и объединять изменения туда и обратно, у вас начнётся кошмар.

Возможно, альтернативой будет color.h или common/color.h файл, который навязывает какую-нибудь структуру вашим файлам.

5
ответ дан 3 December 2019 в 17:20
поделиться

Общие заголовки IMO являются хорошей практикой , если вы ограничиваете их содержанием вещей, которые редко меняются, например

typedef unsigned int UINT32;

Если вы обнаружили, что много редактируете этот файл, то у вас есть вещи, которые не принадлежат ему.

2
ответ дан 3 December 2019 в 17:20
поделиться

Если вам нужны "глобальные" перечисления, то вместо того, чтобы загрязнять глобальное пространство имён, например:

// Types.h

namespace MyTypes
{
    enum Color
    {
        RED,
        BLUE,
        GREEN,
    };
}

Лично я предпочитаю, чтобы перечисления ассоциировались с классом, а не с YMMV.

1
ответ дан 3 December 2019 в 17:20
поделиться

Я предпочитаю быть откровенным о том, что нужно каждому cpp-файлу. Я нахожу, что в долгосрочной перспективе это проще и что это не позволяет "обычным" заголовкам вызывать перекомпиляцию файлов, когда в них нет необходимости. По мере роста проекта, наличие строгой политики 'включать только то, что вам нужно' может помочь сократить время сборки. Ценой этого является небольшая мысль, когда вы изначально строите новый класс. У меня часто есть заголовочные файлы только для одного enum или typedef, и я даже захожу до того, что имею специальную конфигурацию сборки, которая собирается без прекомпилируемых заголовков, и (поскольку я работаю с Visual Studio) использую #pragma hdrstop для определения моих прекомпилируемых заголовков, а не для того, чтобы каждый файл включал общий файл для этой цели.

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

Я рассматриваю общие заголовки как ненужную связь, которая должна быть удалена, и, честно говоря, признак ленивости и недостатка внимания к деталям.

2
ответ дан 3 December 2019 в 17:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: