Нужно уточнить на #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 и игнорирует код во второй раз.
Это сокращает время компиляции, а также означает, что если вы используете плохой / старый компилятор, он не пытается вставить код снова.