#c
#c
Вопрос:
Хорошо, у меня есть этот сценарий.
Класс с именем a, который включает windows.h.
#ifndef a.h
#define a.h
#include <windows.h>
class a
{
};
#endif
Класс с именем b, который включает windows.h.
#ifndef b.h
#define b.h
#include <windows.h>
class b
{
};
#endif
Основной класс как таковой.
#include "a.h"
#include "b.h"
MAIN STUFF
Я хотел бы прояснить следующий момент.
Поскольку я импортирую как a, так и b в main, я обеспокоен тем, что windows.h включается дважды. Так ли это? Если да, то как исправить?
Комментарии:
1. Включите их в соответствующие исходные файлы.
2. Классы ничего не включают.
3. @Махеш. Да, как для класса a, так и для класса be требуется windows.h, поскольку они используют функции, зависящие от windows.h.
4. @Mahesh: Потому что его заголовкам нужен доступ к некоторым символам из WinAPI …?
5. @Mahesh: Это ужасный поступок. Если файлу необходим символ WinAPI, он должен включать заголовок WinAPI. Он абсолютно не должен полагаться на что-то другое, что включало его, чтобы также ранее включало заголовок WinAPI. Заголовки должны быть самодостаточными. (Кроме того, в чем проблема ? Здесь нет проблемы.)
Ответ №1:
#windows.h
должен быть (читай: является) достаточно умным, чтобы это не было проблемой.
-
Они используют «защитные элементы заголовка», чтобы гарантировать безопасность многократного включения в TU, так же, как вы делали в своих файлах
a.h
иb.h
(хотя вам действительно следует выбрать лучшие имена для этих защитных элементов… о, как легко они могут конфликтовать в настоящее время!). -
Чтобы гарантировать безопасность множественного включения в TU (на данный момент это не ваш сценарий), они ограничиваются разрешением только объявлений, а не определений, в файлах заголовков. Остальное будет размещено в двоичных файлах библиотеки, которые являются частью вашей операционной системы. (И, фактически, помимо определений шаблонов / встроенных функций, вы всегда должны отклоняться от определения вещей в заголовках).
Комментарии:
1. «они» = тот, кто написал
windows.h
2. Итак, вы предлагаете, чтобы я #включил <windows.h> в файл cpp, а не в файл h? Я не понимал, что это имеет значение.
3. @user440297: Абсолютно нет. Как сказано в моей первой строке, «это не проблема». Оставьте ваш код таким, какой он есть. Извините, если это было непонятно…
4. Ах, спасибо. Просто некоторая затяжная путаница из-за комментария Махеша, но теперь все ясно.
Ответ №2:
Взгляните на первые две строки в ваших собственных файлах заголовков. Вместе эти строки гарантируют, что препроцессор C включает каждый файл заголовка только один раз. Это стандартный способ написания заголовков для программного обеспечения на C / C . Заголовки основных систем, такие как windows.h, делают то же самое (или что-то подобное), чтобы убедиться, что препроцессор видит файл только один раз.
Ответ №3:
Не должно быть никаких проблем, поскольку windows.h
во включаемом файле есть защитные элементы. Если вы получаете ошибки, переключите версии компилятора или компиляторы в целом.
Ответ №4:
windows.h не включается более одного раза.
действительно, заголовочные файлы c / c используют соглашение о защите включения с помощью защитного блока #ifdef, подобного этому:
#ifndef __WINDOWS_H__
#define __WINDOWS_H__
...
... <windows.h content>
...
#endif
так что на самом деле включено только один раз
Ответ №5:
Да, но не беспокойтесь, поскольку запуск windows.h является:
#ifndef _WINDOWS_
#define _WINDOWS_
Кроме того, вы, возможно, захотите также
#define WIN32_LEAN_AND_MEAN
перед включением Windows, чтобы исключить некоторые из более эзотерических функций.
Ответ №6:
Я на 99% уверен, что у этого windows.h
есть защита от включения, поэтому должно быть абсолютно безопасно включать a.h
и b.h
в один файл — вещи в windows.h
не будут дублироваться
Комментарии:
1. Если вы уверены только на 99%, то это безопасно только на 99%. 🙂
2. Ну, передо мной нет
windows.h
, но я был бы очень, тотально, крайне удивлен, если бы это было не так (:3. @Kiril: Конечно, но считать что-то «абсолютно безопасным», если вы уверены только на 99%, — это плохая практика программирования, не так ли?
4. Правильно, я добавил «должно быть», ок (:. Но если это не так, это будет означать, что «windows» нажимает на спусковой крючок при включении
windows.h
в ваш проект ( «Любой язык позволит вам выстрелить себе в ногу. C предоставит пистолет, зарядит патроны, даст вам выпить, чтобы ваша рука не дрожала, установит оптический прицел и нарисует большую мишень на вашей ноге » )5. «плохая практика программирования» — хорошо, вы должны всегда проверять все, что вы используете, верно. Но вы пытаетесь сказать мне, что вы всегда на 100% уверены в каждой отдельной строке, которую вы пишете в своем коде? Потому что я сомневаюсь в этом. (:
Ответ №7:
Это не должно быть проблемой, потому что важный файл заголовка, подобный Windows.h
, также будет содержать защиту в начале, например
#ifndef _WINDOWS_H
#define _WINDOWS_H
//...code
#endif // _WINDOWS_H
Таким образом, информация в Windows.h
заголовочном файле будет включена только один раз для каждого скомпилированного модуля кода, даже если заголовок повторяется несколько раз, поскольку после первого включения он _WINDOWS_H
определен, поэтому защитные средства заставляют препроцессор пропускать содержимое оставшихся Windows.h
файлов.