Как избежать двойного включения: директива препроцессора или make-файлы - PullRequest
5 голосов
/ 15 февраля 2011

Я работаю над переходом от франкенштейновских и однофайловых программ с тысячами строк к хорошо структурированным и организованным многофайловым программам. Прямо сейчас то, что кажется естественным (наивным), состоит в том, чтобы сделать любовный треугольник включений заголовка для трех из моих файлов:
файл_1 включает файл_2, файл_4
файл_2 включает файл_3, файл_4
файл_3 включает файл_1 .... и т. д. и т. д.
Эти файлы имеют переменные, методы, структуры и т. Д., Которые мне нужны между другими файлами.

И, конечно, я получаю ошибки двойного включения.

Мой вопрос: следует ли мне избегать этих проблем, используя директивы препроцессора в заголовках (например, включая структуры, методы и т. Д. Целиком в заголовке), или я должен компилировать с использованием make-файла (который я слышу) также может быть использован для решения этой проблемы --- но я никогда не делал)?

Ответы [ 4 ]

13 голосов
/ 15 февраля 2011

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

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

3 голосов
/ 15 февраля 2011

Директивы препроцессора и заголовки, содержащие декларации, общие структуры и т. Д., - это путь. Makefiles просто помогает скомпилировать исходники и связать объектные файлы с внешними библиотеками, чтобы сформировать окончательный двоичный файл, это не поможет решить проблему множественного включения. В двух словах, объявите следующее в заголовочном файле:

  • * 1004 Структуры *
  • общая переменная как extern (и определить ее в одном из .c файлов)
  • объявление метода (и определение методов в одном из файлов .c)

защитите их с помощью #IFNDEF и #ENDIF, затем включите заголовочный файл в различные файлы .c ...

1 голос
/ 15 февраля 2011

заголовочных файлов

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

Если вы используете только ссылку или указатель на класс, объявите его только вперед (не включая файл хедера).

Таким образом вы можете прервать включение циклического заголовка.

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

1 голос
/ 15 февраля 2011

Примером включения защиты для inv_tree.h будет

#ifndef INV_TREE_H
#define INV_TREE_H
...
#endif

Окружая содержимое "inv_tree.h" с помощью сторожа, он проверяет, была ли определена погода INV_TREE_H, прежде чем включать "inv_tree.h". Если он не был определен, он определяет его и включает "inv_tree.h", в противном случае он не включает он

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