Заголовок C ++ защищает вокруг объекта и использования?

Я привык помещать охрану заголовка вокруг моих объектов, таких как:

#ifndef SOMETHING_H
#define SOMETHING_H

class Something {
...
}
#endif

но мне дали код, где они также делают:

#ifndef SOMETHING_H
#include "something.h"#endif

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

5

Решение

Это обсуждается довольно подробно здесь:
http://c2.com/cgi/wiki?RedundantIncludeGuards

Вот основные моменты:

  • Да, это избыточно, но для некоторых компиляторов это может быть быстрее, потому что компилятор будет избегать открытия файла заголовка, если в этом нет необходимости.
  • «Хорошие компиляторы делают эту идиому ненужной. Они замечают, что заголовок использует идиому include-guard (то есть, что весь код без комментариев в файле заключен в скобки с #ifndef). Они хранят внутреннюю таблицу заголовочных файлов и guard макросы. Перед открытием любого файла они проверяют текущее значение защиты, а затем пропускают весь файл. «
  • «У избыточных охранников есть несколько недостатков. Они делают включающие разделы значительно труднее для чтения. Они, ну, в общем, избыточны. Они пропускают имя охранника, которое должно быть секретной деталью реализации заголовка. Если, например, кто-то переименовывает охрану, они может забыть обновить все места, где предполагается использовать имя охранника. Наконец, они ошибаются, если кто-то добавляет код за пределами защиты. И, конечно, это всего лишь взлом эффективности во время компиляции. Используйте только тогда, когда все остальное терпит неудачу ».
5

Другие решения

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

5

Это полезно иметь в заголовочных файлах и файлах определения классов, чтобы при компиляции, если на файл ссылаются в цикле (a.cpp ссылается на ah и b.cpp, а b.cpp также ссылается на ah, ah больше не будет читаться ) или другие подобные случаи.

Больше всего меня беспокоит то, что похоже на ваш вопрос, так это то, что одно и то же имя константы определяется в разных файлах и, возможно, мешает компилятору видеть некоторые необходимые для просмотра константы, классы, типы и т. Д., Как это будет » Поверьте «, что файл был» уже прочитан «.

Короче говоря, поместите разные константы #ifndef в разные файлы, чтобы избежать путаницы.

0

Цель этого — сэкономить время компиляции. Когда компиляция видит #include "something.h", он должен выйти и получить файл. Если он делает это десять раз, а последние девять в целом составляют:

#if 0
...
#endif

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

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

0
По вопросам рекламы [email protected]