Как включить заголовочные файлы - PullRequest
13 голосов
/ 18 сентября 2010

Имеет ли значение, как я импортирую заголовочные файлы?Я видел двойные кавычки, а также использованные стрелки.

#include <stdlib.h>
#include "Some_Header.h"

Имеет ли значение, если они также написаны заглавными буквами?Поэкспериментируя с этим, кажется, что это не имеет значения, но я полагаю, что для учебных пособий должна быть причина, по которой они делают это так, как они делают.вне файла это было определено в?Скажем, у меня есть one.cpp и two.cpp.

В one.cpp:

class Something {
    ...

В two.cpp:

class SomethingElse {
    Something *example;
    ...

Как это?В Java вы просто вводите имя класса как «public».В C ++ спорные классы кажутся немного сложнее ..

Ответы [ 5 ]

27 голосов
/ 18 сентября 2010

Угловые скобки в директивах #include означают, что путь поиска ограничен «системными» каталогами.Двойные кавычки означают, что путь поиска включает каталог current , за которым следуют системные каталоги.

Случай имени файла имеет значение, когда ваша ОС использует файловую систему, чувствительную к регистру.Похоже, вы используете Windows или Mac OS X, где имена файлов по умолчанию не чувствительны к регистру.

7 голосов
/ 18 сентября 2010

Сначала простой вопрос:

Имеет ли значение, если они также написаны заглавными буквами определенным образом?

В большинстве случаев includes относится к файлами компилятор должен быть в состоянии найти файл, который вы включаете в систему.По этой причине капитализация имеет значение во всех системах, где файловая система чувствительна к регистру.Если вы хотите сохранить минимум переносимости, вы должны быть последовательны в именах файлов и include.(Все linux и mac os по умолчанию имеют чувствительные к регистру файловые системы, в Windows вы также можете настроить NTFS так, чтобы они были чувствительными к регистру).

Теперь, действительно ли имеет значение, как называется файл?Нет, пока вы последовательны во включениях.Также обратите внимание, что для облегчения включения рекомендуется следовать шаблону.

Имеет ли значение, как я импортирую файлы заголовков?

Стандарт не совсем понятен для этоготочка, и разные реализации шли разными путями.Стандарт определяет, что они могут быть разными, так как набор местоположений и порядок, в котором компилятор будет искать включенный файл, определяется реализацией и может отличаться, если включение выполняется с помощью угловых скобок или двойных кавычек.Если при включении в кавычки не удается найти файл, компилятор должен выполнить обработку для включения, как если бы оно было записано в угловых скобках.

#include <x.h> // search in order in set1 of directories
#include "x.h" // search in order in set2 of directories
               // if search fails, search also in set1

Это означает, что если файл присутствует только в set1,оба типа включений найдут его.Если файл присутствует в set2, но не в set1, его найдет только цитата include.Если в set1 и set2 присутствуют разные файлы с одинаковыми именами, то каждый тип включения будет находить и включать разные файлы.Если в общем подмножестве set1 и set2 присутствуют два файла с одинаковыми именами, но порядок наборов различен, каждый тип включения может найти свой файл.

Возвращаясь к реальному миру, большинство компилятороввключать только текущий каталог в set2, причем set1 - это все места включения системы (которые обычно могут быть расширены с помощью аргументов компилятора). В этих случаях, если файл присутствует только в текущем каталоге, #include "a.h" найдет его, но #include <a.h> не будет.

Теперь, является ли это обычным поведением, существует некоторая подразумеваемая семантика, которая является идиоматической в ​​C / C ++.Обычно квадратные скобки используются для включения системных заголовков и внешних заголовков, в то время как двойные кавычки используются для включения локальных файлов.Существует серая зона относительно того, следует ли считать библиотеку в том же проекте локальной или внешней .То есть, даже если всегда будет работать включение с двойными кавычками, большинство людей будут использовать угловые кавычки для ссылки на заголовки, которые не являются частью текущего модуля .

Наконец, пока нет компилятора, которыйЯ знаю, делает ли это, стандарт позволяет реализации (компилятору) не создавать стандартные заголовки в виде реальных файлов, а обрабатывать включение стандартных заголовков внутри.Это единственный случай, когда теоретически #include "vector" может не включать определения класса std::vector (или любого другого стандартного заголовка).Но это не практический вопрос, и я не думаю, что он когда-либо будет.

7 голосов
/ 18 сентября 2010

Вопрос 1

Имеет ли значение, как я импортирую заголовочные файлы?Имеет ли значение, если они также написаны заглавными буквами определенным образом?

Это не имеет значения, но обычная практика такова:

  • Используйте угловые скобки для системных заголовков.
  • Пользовательские двойные кавычки для пользовательских заголовков (Ваши собственные заголовки)

Вопросы 2 и 3

Еще один вопрос (из Java здесь)Как получить доступ к классу вне файла, в котором он был определен?

Вам нужно поместить определение класса в файл заголовка и включить этот файл заголовка везде, где вы хотите использовать класс.Для вашего случая это будет выглядеть ниже.

//One.h
#ifndef ONE_H
#define ONE_H
class Something
{
public:
    void doSomething(){}

};
#endif

//Two.cpp
#include "One.h"
class SomethingElse
{
   SomeThing *example;
};
7 голосов
/ 18 сентября 2010

Угловые скобки ищут заголовок в системных каталогах заголовков (например, /usr/include). Кавычки - это просто абсолютный или относительный путь, например /path/to/header.h или ../headers/abc.h.

Для доступа к классам из других файлов, просто #include другой файл с классом. Обязательно структурируйте свою программу так, чтобы ни один файл не был включен более одного раза.

0 голосов
/ 18 сентября 2010

Во-первых, #include является директивой препроцессора C и не является строго частью языка C ++ как такового. Вы можете узнать больше об этом здесь , хотя это специально для препроцессора GNU C, поэтому может отличаться от того, что вы используете. Я думаю, что вы всегда должны принимать во внимание чувствительность к регистру во включаемых файлах. Невыполнение этого требования может затруднить перенос кода на чувствительную к регистру ОС, такую ​​как UNIX.

Использование "" или <> довольно тонкое, как объяснено выше, и в большинстве случаев вы не заметите никакой разницы. Использование "" обычно сначала ищет текущий каталог. Я склонен не использовать это как:

  • Я знаю, где находятся мои заголовки - я всегда указываю их с -I в строке компиляции.
  • Меня уже поймали, когда локальная копия заголовка вышла за центральную копию, которую я надеялся получить.

Я также заметил некоторые побочные эффекты, например, при использовании make для создания деревьев зависимостей (я не могу вспомнить проблему - она ​​по-разному относилась к различным включениям, следуя некоторым, а не другим, но это было около 7 лет назад)

Во-вторых, на ваш вопрос о том, как ссылаться на функции в других файлах, отвечает здесь /

...