Именование включает охранников
Как С++ включают в себя защитные устройства, которые обычно называются? Я очень часто вижу это:
#ifndef FOO_H
#define FOO_H
// ...
#endif
Однако я не считаю это очень интуитивным. Не видя имени файла, трудно сказать, что такое FOO_H
и для чего оно относится.
Что считается лучшей практикой?
Ответы
Ответ 1
По собственному опыту, соглашение должно называть охранники включения после содержащего их заголовочного файла, за исключением того, что имя все в шапке, а период заменяется знаком подчеркивания.
Итак test.h
становится TEST_H
.
Реальные примеры этого включают Qt Creator, который следует этому соглашению при автогенерации файлов заголовков классов.
Ответ 2
Я лично следую рекомендациям Boost. Это, возможно, одна из самых больших библиотек С++ хорошего качества, и у них нет проблем.
Это выглядит так:
<project>_<path_part1>_..._<path_partN>_<file>_<extension>_INCLUDED
// include/pet/project/file.hpp
#ifndef PET_PROJECT_FILE_HPP_INCLUDED
который:
- legal (обратите внимание, что начало с помощью
_[A-Z]
или содержащее __
не является)
- легко сгенерируется
- гарантированно будет уникальным (в качестве защитника) в рамках проекта (иначе у вас есть два файла в одном месте)
- гарантированно не будет использоваться ни для чего другого (если вы закончите другой макрос с помощью
INCLUDED
, вы портитесь для боя)
Я читал о GUID, но они выглядят странно.
И, очевидно, я предпочел бы, чтобы все компиляторы реализовали #pragma once
(или лучше, #pragma multiple
и "once" - поведение по умолчанию...)
Ответ 3
Взято непосредственно из руководства по стилю google:
Все файлы заголовков должны содержать #define guard для предотвращения множественного включения. Формат имени символа должен быть <PROJECT> _ <PATH> _ <FILE> _H_. Чтобы гарантировать уникальность, они должны основываться на полном пути в исходном дереве проекта. Например, файл foo/src/bar/baz.h в проекте foo должен иметь следующую защиту:
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_
Я использую этот стиль в своих проектах.
Ответ 4
Посмотрите на код, который # включает ваш заголовок.
Если это что-то вроде:
#include "mylib/myheader.h"
mylib/myheader.h
уже является уникальным именем. Просто капитализируйте и замените/и. с _
#define MYLIB_MYHEADER_H
Если у вас есть два заголовка на вашем пути include с тем же именем относительно пути include, у вас уже есть столкновение на этом уровне.
Ответ 5
Замените FOO_H
на FOO_H_INCLUDED
и понятнее.
Ответ 6
Как упоминалось ранее, очень распространенное соглашение заключается в использовании прописной версии имени, а точка заменяется на символ подчеркивания: foo.h → FOO_H
Однако это может привести к конфликтам имен с простыми и/или общими именами. По этой причине автогенерированный заголовок, такой как stdafx.h в непустых проектах Visual C С++, добавляет некоторую случайную строку, например:
#ifndef FOO_H__NsknZfLkajnTFBpHIhKS
#define FOO_H__NsknZfLkajnTFBpHIhKS
#endif
http://www.random.org/strings/ - полезный случайный генератор для этого.
Кроме того, если файл является частью какого-либо подмодуля или его содержимое находится в одном конкретном пространстве имен, я также добавляю это к защите:
#ifndef SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS
#define SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS
namespace somecomponent
{
...
}
#endif
Ответ 7
Обычно я использую что-то вроде FOO_H_INCLUDED_
. Несколько (Microsoft) заголовков имеют то, что очень похоже на строковое представление GUID, но мне никогда не нужно было ничего такого, что было бы сложнее.
Ответ 8
Обычно люди делают это по имени файла, поэтому каждый код файла только компилируется и добавляется один раз. Вы могли бы сделать FOO_H всем, что хотите, но почти все, что я когда-либо кодировал или видел, использовал имя файла. Просто убедитесь, что он уникален, потому что вы не хотите, чтобы ваш FOO_H противоречил кому-то еще FOO_H.
Ответ 9
Я обычно смотрю, в какое время это время, и просто добавляем это к концу, т.е. FOO_H_248
, это дополнительная мера предосторожности, и вам никогда не придется его запоминать, так что вам не нужно беспокоиться о том, тот факт, что он загадочный.