|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Заголовочные файлы, ошибка повторения включений
Ошибка повторения включений Мы упоминали, что нельзя определять функцию или переменную в заголовоч- ном файле, который будет использован несколькими исходными файлами. Это приводит к ошибкам повторных определений. Подобная проблема возникает и тогда, когда по ошибке включают один и тот же заголовочный файл дважды. Как такое может случиться? Да запросто: //файл app.cpp #include "headone.h" #include "headone.h" Но это еще ничего. Представьте себе, что у вас есть исходный файл app.cpp и два заголовочных — headone.h и headtwo.h. К тому же headone.h включает в себя headtwo.h К сожалению, про это обстоятельство забывают и включают оба файла в app.cpp: //файл headtwo.h int globalVar;
//файл headone.h #include "headtwo.h"
//файл app.cpp #include "headone.h" #include "headtwo.h" Что теперь будет после компиляции app.cpp? Так как директивой #include мы вставили заголовочные файлы, реальное содержимое исходного файла будет таково: //файл app.cpp ...
int globalVar; //из headtwo.h через headone.h ...
int globalVar; //напрямую из headtwo.h Разумеется, компилятор сообщит, что globalVar определена дважды. Предупреждение ошибок повторения включений С рассеянностью приходится бороться. Вот как можно предупредить ошибки повторных определений даже при ошибках повторения включений: определения в заголовочном файле следует начинать с директивы препроцессора: #if!defined(HEADCOM) (На месте HEADCOM может быть любой идентификатор.) Это выражение говорит о том, что если HEADCOM еще не был определен (восклицательный знак означает логическое отрицание), то весь текст отсюда и до обеда, точнее, до #endif (закрывающая директива для #if), будет просто вставляться в исходный файл. В противном случае (если HEADCOM уже определен ранее, в чем можно удостовериться с помощью директивы #define HEADCOM) следующий за #if текст не будет включен в исходный код. Как говорят в американских фильмах, он погиб в этой мясорубке. Поскольку переменная HEADCOM не была определена до того, как эта директива встретилась впервые, но сразу же после #if!defined() оказалась определенной, весь текст, заключенный между #if и #endif, будет включен один раз, но это будет первый и последний раз. Вот как это делается: #if!defined(HEADCOM) //Если HEADCOM еще не определен. #define HEADCOM //определить ее int globalVar; //определить переменную int func(int a, int b) //определить функцию { return a+b; } #endif //закрывающая условие директива Этот подход следует использовать всегда, когда существует возможность случайно включить заголовочный файл в исходный более одного раза. Раньше использовалась директива #ifndef, это то же самое, что #if!defined(); вы можете встретить ее во многих заголовочных файлах, входящих в комплект поставки вашего компилятора. Тем не менее от ее использования теперь отказались. Понятно, что эта «защита от дурака» с использованием #if!defined() сработа- ет только в том случае, если определение globalVar (или любой другой переменной или функции) может случайно быть включено несколько раз в один и тот же исходный файл. Она не сработает, если globalVar определена в.H-файле, и его включают в разные файлы A и B, Препроцессор бессилен в этом случае, он не может определить наличие одинаковых выражений в отдельных файлах, поэтому все станет известно компоновщику, который, конечно же, нажалуется на то, что globalVar определена несколько раз.
Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.005 сек.) |