АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Заголовочные файлы, ошибка повторения включений

Читайте также:
  1. Во-вторых, увеличение числа актов снижает воздействие кульминаций и приводит к многочисленным повторениям.
  2. Глава 6. Фундаментальная ошибка атрибуции
  3. Глава 6. Фундаментальная ошибка атрибуции
  4. ДЕЛИТЬСЯ ЧУВСТВАМИ С РЕБЕНКОМ — ОШИБКА
  5. Загадка» или «ошибка» Лапиера?
  6. Зачем нужны негативные повторения в бодибилдинге и пауэрлифтинге?
  7. Критерии параметрического метода оценки и способы их расчета (ошибка, репрезентативности средних и относительных величин, доверительные границы средних и относительных величин).
  8. МАТЕРИАЛ ДЛЯ ПОВТОРЕНИЯ
  9. МАТЕРИАЛ ДЛЯ ПОВТОРЕНИЯ
  10. МАТЕРИАЛ ДЛЯ ПОВТОРЕНИЯ
  11. МАТЕРИАЛ ДЛЯ ПОВТОРЕНИЯ

 

Ошибка повторения включений

Мы упоминали, что нельзя определять функцию или переменную в заголовоч-

ном файле, который будет использован несколькими исходными файлами. Это

приводит к ошибкам повторных определений. Подобная проблема возникает

и тогда, когда по ошибке включают один и тот же заголовочный файл дважды.

Как такое может случиться? Да запросто:

//файл 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 определена несколько раз.

 


1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.003 сек.)