Нужно уточнить на #ifndeF#define

Код, который я работаю, имеет несколько заголовков и исходных файлов для разных классов face.cc, face.hh, cell.cc, cell.hh edge.cc edge.hh и заголовки содержат, как это,

#ifndef cellINCLUDED
#define cellINCLUDED

#ifndef faceINCLUDED
#define faceINCLUDED

Я видел через http://www.cplusplus.com/forum/articles/10627/ и увидел, как написать, например, включить охрану

#ifndef __MYCLASS_H_INCLUDED__
#define __MYCLASS_H_INCLUDED__

Итак, в приведенном выше коде, над которым я работаю, компилятор автоматически понимает, что ищет face.hh или же cell.hh файлы?

лучше вопрос: пишет __CELL_H_INCLUDED__ такой же как cellINCLUDED?

4 ответа

Решение
#ifndef __MYCLASS_H_INCLUDED__
#define __MYCLASS_H_INCLUDED__

Итак, в приведенном выше коде, над которым я работаю, компилятор автоматически понимает, что он ищет файлы face.hh или cell.hh?

Нет, компилятор не понимает автоматически, что вы имеете в виду.

Что действительно происходит, так это то, что при компиляции модуля перевода компилятор содержит список глобально определенных MACRO. Итак, что вы делаете, это определение MACRO __MYCLASS_H_INCLUDED__ если он еще не существует

Если этот макрос определен, то #ifndef до тех пор #endif не будет проанализирован фактическим компилятором. Следовательно, вы можете проверить наличие этого MACRO, чтобы определить, проанализировал ли компилятор этот заголовочный файл, чтобы включить его один и только один раз в модуль перевода... Это происходит потому, что компилятор компилирует каждый модуль перевода как один сведенный файл (после объединения все #includes )

Смотрите https://en.wikipedia.org/wiki/Include_guard

Пишет __CELL_H_INCLUDED__ такой же как cellINCLUDED?

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

Я предпочитаю что-то вроде этого: CELL_H_INCLUDED

Если вы используете cellINCLUDED есть вероятность, что когда-нибудь кто-нибудь может использовать его в качестве идентификатора в этой единице перевода

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

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

При этом каждый компилятор, заслуживающий внимания, в настоящее время поддерживает #pragma onceи, возможно, вы могли бы остановиться на этом.

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

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

Нет, это, по сути, говорит компилятору / парсеру, что, если это уже было введено в программу, не загружайте его.

Это должно быть вверху (и иметь #endif внизу) вашего файла.h.

Допустим, у вас есть mainProgram.cpp и Tools.cpp, причем каждый из этих файлов загружает fileReader.h. Когда компилятор компилирует каждый файл cpp, он попытается загрузить fileReader.h. если вы не скажете это, он загрузит весь файл fileReader в два раза.

ifndef = если не определено

поэтому, когда вы используете их (и #endif ПОСЛЕ всего вашего кода в файле.h), вы говорите:

if not defined: cellINCLUDED
then define: cellINCLUDED with the following code:
[code]
end of code

таким образом, когда он загружает код в ваш файл.h второй раз, он обращается к биту if not not и игнорирует код во второй раз.

Это сокращает время компиляции, а также означает, что если вы используете плохой / старый компилятор, он не пытается вставить код снова.

Другие вопросы по тегам