Включение заголовочных файлов в Visual Studio - PullRequest
1 голос
/ 22 октября 2009

Предположим, у меня есть решение с 3 проектами X, Y и E.

E создаст исполняемый файл, а X и Y создадут статические библиотеки, так что Y включает в себя файлы заголовков X, а E включает файлы заголовков Y.

Теперь мой вопрос: почему я должен включать каталог файлов заголовков X в E?

Ответы [ 4 ]

4 голосов
/ 22 октября 2009

Вот почему:

  1. Возможно, что некоторая функция в проекте Y принимает аргумент (или возвращает значение) типа, объявленного в X.
  2. Если это так, компилятору, возможно, придется создавать эти объекты аргумента (или возвращаемого значения) при компиляции E.
  3. Если это так, файлы заголовков из X абсолютно необходимы в E.
1 голос
/ 22 октября 2009

Вы можете избежать этой ситуации, если построите Y так, чтобы его зависимости от X были полностью инкапсулированы. Это может или не может быть возможным в зависимости от специфики X и Y. Но если интерфейс, который Y представляет для E, не должен содержать какие-либо подробности X, то проект E не должен даже косвенно включать Заголовки из X. В этом случае только файлы реализации Y (файлы .c или .cpp) будут содержать заголовки из X. Использование предварительных объявлений для типов в X в заголовках Y может помочь добиться инкапсуляции X в Y.

Это хорошая цель для достижения, но это не всегда возможно, и даже когда это возможно, это может потребовать больше усилий, чем вы (или ваше руководство) хотели бы выдвинуть.

1 голос
/ 22 октября 2009

Иногда можно реструктурировать заголовочные файлы для C ++, чтобы использовать предварительные объявления, чтобы избежать ситуации, которую вы описываете. Вот пример: Трюки с зависимостями заголовка C ++ .

Простой случай:

X.h

class X {
  //...
};

Y.h

// #include <X.h> -- remove this
class X; // add forward declaration
class Y {
  X *m_px; // must be a pointer, not a value,
           // otherwise the size of X would need to be known
  //...
};

Y.cpp

#include <X.h> // need to add it here
//...
0 голосов
/ 22 октября 2009

Краткий ответ: «Почему я должен включать каталог заголовочных файлов X в E?» ... Вы не должны. Клиенту Y не нужно знать, что Y зависит от X.


Длинный ответ: Вы должны включать заголовок X в E, только если интерфейс (подписи) Y использует вещи, объявленные в заголовке X. Но если заголовок Y был " правильно построенный ", тогда они будут включать заголовки X в сам заголовок Y, и вам не нужно будет явно включать заголовок X в E (включая заголовок Y будет автоматически включать заголовок X).

Под «правильно построенным» я подразумевал, что если подписи в Y1.h в Y зависят, скажем, от X3.h и X7.h, то Y1.h должен включать эти файлы (прямо или косвенно). Таким образом, любой клиент Y1.h не должен знать, что это за зависимости, и должен будет включать эти зависимости отдельно в результате. В качестве простого теста, .cpp, состоящий из следующей строки, должен компилироваться без проблем:

#include "Y1.h"

Хорошей практикой является включение "Y1.h" перед включением любого другого файла в Y1.cpp. Если в Y1.h отсутствуют зависимости, компилятор сообщит вам.

...