Подтвердить что ты не робот

Защита заголовка в C++ и C

На сайте LearnCpp.com | 1.10 - Первый взгляд на препроцессор. В разделе " Защитники заголовков" есть эти фрагменты кода:

add.h:

#include "mymath.h"
int add(int x, int y);

subtract.h:

#include "mymath.h"
int subtract(int x, int y);

main.cpp:

#include "add.h"
#include "subtract.h"

При реализации защиты заголовка он упоминается следующим образом:

#ifndef ADD_H
#define ADD_H

// your declarations here

#endif
  • Что может быть здесь? И, если int main() придет после #endif?
  • _H ли _H конвенцию или должен делать что-то?

Благодарю.

4b9b3361

Ответ 1

FILENAME_H - это соглашение. Если вы действительно хотели, вы могли бы использовать #ifndef FLUFFY_KITTENS как защитник заголовка (при условии, что он не определен нигде), но это было бы сложной ошибкой, если бы вы определили ее где-то в другом месте, например, количество котят для чего-то или другого.

В файле заголовка add.h объявления буквально находятся между #ifndef и #endif.

#ifndef ADD_H
#define ADD_H

#include "mymath.h"
int add(int x, int y);

#endif

Наконец, int main() не должен находиться в файле заголовка. Он всегда должен находиться в файле .cpp.

Чтобы очистить его:

#ifndef ADD_H в основном означает "если ADD_H не был #defined в файле или во включенном файле, затем скомпилируйте код между #ifndef и #endif директивами". Поэтому, если вы пытаетесь #include "add.h" более одного раза в файле .cpp, компилятор увидит, что ADD_H уже был #defined, и будет игнорировать код между #ifndef и #endif. Защитники заголовков предотвращают включение файла заголовка несколько раз в один и тот же файл .cpp. Защитники заголовка не препятствуют включению других файлов .cpp из файла заголовка. Но все файлы .cpp могут включать защищенный заголовочный файл только один раз.

Ответ 2

  • Результатом предварительной обработки одного файла реализации (.cpp) является единица перевода (TU).

  • Заголовки могут включать в себя другие заголовки, поэтому заголовок может косвенно включаться несколько раз в один и тот же TU. (Ваш пример mymath.h).

  • Определения могут возникать не более одного раза за TU. (Некоторые определения также не должны быть в нескольких TU, этот случай немного отличается и не обсуждается здесь.)

  • Проблема заключается в том, что защита защищает несколько ошибок определения, когда данный заголовок включен более одного раза в один TU.

  • Включите защитную работу путем "обертывания" содержимого заголовка таким образом, чтобы второй и последующие включения не были. Директивы # ifndef/# define должны быть первыми двумя строками файла, а #endif должен быть последним.

  • Включить охранники используются только в заголовках. Не определяйте свою основную функцию в заголовке: поместите ее в файл реализации.

Если у вас есть заголовок, который будет определять тип и объявить функцию, но также нужен сам заголовок:

#include "other_header.h"

struct Example {};

void f();

"Обертка" с включенными охранниками дает полное содержимое файла:

#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE

#include "other_header.h"

struct Example {};

void f();

#endif

Имя, используемое для защиты включения, должно быть уникальным, иначе конфликтующие имена дадут запутанные результаты. Эти имена - это только простые макросы, и на языке, который обеспечивает определенный стиль, нет ничего. Тем не менее, соглашения по проектам обычно предъявляют требования. Существует несколько разных типов стилей, которые можно найти здесь: SO и в других местах; этот ответ дает хорошие критерии и хороший обзор.

Ответ 3

Все защитники заголовков позволяют только включить ваши заголовки один раз. (Если они включены несколько раз, они игнорируются.)

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

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

Ответ 4

Нет, int main() идет в .cpp. Декларации - это еще один материал, который вы собираетесь добавить в заголовок. _H - это соглашение, вы можете видеть различные соглашения защиты заголовка.

Ответ 5

Объявляю объявление в файле заголовка и определениях или int main() входит в файл source.cpp.

_H нужно просто указать, что кто-то будет включать файлы заголовков, используя include guard.

Если вы используете MSVС++, вы также можете использовать #pragma once

Ответ 6

Я придумал лучшую защиту, когда есть перекрестные ссылки между двумя классами, чтобы избежать размещения предварительных объявлений вручную. Решение здесь: fooobar.com/info/67334/...