Работаю в Visual C++.NET 2005
Делаю простейший пример:
// -- файл TArray.h ---------------------------
#include <iostream>
using namespace std;
class Array // интерфейс: определение класса Array
{ /* ... */ };
// -- файл TArray.cpp -------------------------
#include "TArray.h" // подключение интерфейса
#include <iostream>
using namespace std;
Array::Array( Array::size_type size, Array::value_type k )
{ /* ... */ }
// внешние определения остальных методов
// -- файл main.cpp ---------------------------
#include "TArray.h" // подключение интерфейса
#include <iostream>
using namespace std;
int main()
{ /* ... */ };
Обратите внимание, ни pragmы, ни стража в заголовке TArray.h не прописано. Тем не менее, все транслируется и собирается и работает корректно.
В проекте это три отдельных файла. По идее линкер должен выдать повторное определение. Но не дает
Чуть усложняю пример:
// -- файл TArray.h ---------------------------
#ifndef _ARRAY_ // страж определен?
#define _ARRAY_ // если нет - определяем
#include <iostream>
using namespace std;
class Array // интерфейс: определение класса Array
{ /* ... */ };
#endif // конец #ifndef
// -- файл TArray.cpp -------------------------
#include "TArray.h" // подключение интерфейса
#include <iostream>
using namespace std;
Array::Array( Array::size_type size, Array::value_type k )
{ /* ... */ }
// внешние определения остальных методов
// --------------------------------------------
// -- файл TFlex.h ----------------------------
//#pragma once // компилировать один раз
#include "TArray.h"
class Flex: public Array
{ /* ... */ };
#endif // конец #ifndef
// -- файл TFlex.cpp -------------------------
#include "TArray.h"
#include "TFlex.h"
// реализация конструкторов
Flex::Flex():Array(minSize), Count() {}
// внешние определения остальных методов
// --------------------------------------------
// -- файл main.cpp ---------------------------
#include "TArray.h" // подключение интерфейса Array
#include “TFlex.h” // подключение интерфейса Flex
#include <iostream>
using namespace std;
int main()
{ /* ... */ };
Я закомментировал прагму во TFlex.h, поскольку и так компилировалось. В этом варианте потребовалось прописать стража в TArray.h, так как линкер выдал сообщение о повторном определении.
Такое чувство, что один раз система по умолчанию сама разруливает, а последующие включения — уже нет.