У меня очень простой проект в VS2012 с использованием предварительно скомпилированных заголовков. Я знаю, что я должен добавить все «общие» включения в stdafx.h и что мне нужно включить это в каждый файл .cpp. Таким образом, базовая настройка выглядит так:
foo.h:
#ifndef FOO_H
#define FOO_H
class Foo {
public:
Foo();
~Foo();
void do(string str);
};
#endif
Foo.c:
#include "stdafx.h"#include "Foo.h"
void Foo::do(string str) {}
в stdafx.h:
#include <string>
using namespace std;
Без предварительно скомпилированных заголовков я бы поставил #include <string>
в foo.h, так как он должен знать об объявлении string
, Но как этот foo.h знать о string
в этой настройке? (Обратите внимание, что stdafx.h включен только в файлы .cpp).
Примечание: у меня есть рабочий пример, в котором используются предварительно скомпилированные заголовки; вопрос в том, как это работает.
Это связано с тем, что компилятор обрабатывает заголовки в том порядке, в котором они отображаются в основном модуле компиляции.
Поскольку .cpp
файл включен <string>
(косвенно через "stdafx.h"
), содержание <string>
известны компилятору и могут использоваться кодом, который следует, даже кодом, извлеченным из заголовочных файлов.
Это хрупкий, потому что включение вашего заголовочного файла без предварительного включения <string>
приведет к ошибкам.
Вы можете посмотреть на скомпилированные заголовки как своего рода кеш для заголовочных файлов. Компилятор анализирует набор заголовков, когда он впервые сталкивается с ним (обычно при компиляции stdafx.cpp), компилирует их, а затем готовит результаты для любого модуля, который в них нуждается.