Есть ли какой-либо материал о том, как правильно использовать #include
?
Я не нашел текстового текста на C/С++, который подробно объясняет это использование.
В формальном проекте я всегда путаюсь с этим.
Как правильно использовать директиву #include?
Ответ 1
- Проверьте крупномасштабный дизайн программного обеспечения на С++ от Джона Лакоса, если у вас есть деньги.
- В руководстве по кодированию Google С++ также есть некоторые вещи OK.
- Проверьте материалы Sutter Herb онлайн (блог).
В основном вам нужно понять, где включить заголовки НЕ требуются, например. форвардная декларация. Также попробуйте убедиться, что включенные файлы компилируются один за другим и помещают #includes в h файлы, когда это необходимо (например, шаблоны).
Ответ 2
Большая, которая всегда сбивала меня с толку, такова:
Выполняется поиск в пути заголовка:
#include <stdio.h>
Выполняется поиск в вашем локальном каталоге:
#include "myfile.h"
Вторая вещь, которую вы должны делать с КАЖДОМ заголовком, такова:
myfilename.h:
#ifndef MYFILENAME_H
#define MYFILENAME_H
//put code here
#endif
Этот шаблон означает, что вы не можете упасть на переопределение заголовков в своей компиляции (приветствия orsogufo для указания на меня, это называется "включить охрану" ). Прочитайте, как компилятор C на самом деле компилирует файлы (перед связыванием), потому что это сделает мир #define и #include очень полезным для вас, компилятор C, когда дело доходит до разбора текста, не очень умный. (Сам компилятор C - это другое дело)
Ответ 3
Таким образом, ваш компилятор может поддерживать 2 уникальных пути поиска для включенных файлов:
Неформально мы могли бы назвать систему include path и указать путь пользователя.
#include <XX> выполняет поиск в системе, включая путь.
#include "XX" ищет путь включения пользователя, затем система включает путь.
Проверка черновика стандарта n2521:
Раздел 16.2:
2 A preprocessing directive of the form
# include < h-char-sequence> new-line
searches a sequence of implementation-defined places for a header identified
uniquely by the specified sequence between the < and > delimiters, and
causes the replacement of that directive by the entire contents of the
header. How the places are specified or the header identified is
implementation-defined.
3 A preprocessing directive of the form
# include " q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the
source file identified by the specified sequence between the " " delimiters.
The named source file is searched for in an implementation-defined manner.
If this search is not supported, or if the search fails, the directive is
reprocessed as if it read
# include < h-char-sequence> new-line
with the identical contained sequence (including > characters, if any)
from the original directive.
Примером этого может быть gcc
-isystem <dir> Add <dir> to the start of the system include path
-idirafter <dir> Add <dir> to the end of the system include path
-iwithprefix <dir> Add <dir> to the end of the system include path
-iquote <dir> Add <dir> to the end of the quote include path
-iwithprefixbefore <dir> Add <dir> to the end of the main include path
-I <dir> Add <dir> to the end of the main include path
Чтобы узнать, где находится ваш gcc, выполните следующие действия:
g++ -v -E -xc++ /dev/null -I LOOK_IN_HERE
#include "..." search starts here:
#include <...> search starts here:
LOOK_IN_HERE
/usr/include/c++/4.0.0
/usr/include/c++/4.0.0/i686-apple-darwin9
/usr/include/c++/4.0.0/backward
/usr/local/include
/usr/lib/gcc/i686-apple-darwin9/4.0.1/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
Итак, как вы используете это знание.
Есть несколько школ мысли. Но я всегда перечисляю свои библиотеки от наиболее конкретных до самых общих.
Пример
Файл: plop.cpp
#include "plop.h"
#include "plop-used-class.h"
/// C Header Files
#include <stdio.h> // I know bad example but I drew a blank
/// C++ Header files
#include <vector>
#include <memory>
Таким образом, если заголовочный файл "plop-used-class.h" должен включать <vector> это будет рассмотрено компилятором. Если бы я положил <vector> наверху эта ошибка была бы скрыта от компилятора.
Ответ 4
В дополнение к другим комментариям помните, что вам не нужно # включать заголовок в другой заголовок, если у вас есть только указатель или ссылка. Например:.
Требуется заголовок:
#include "Y.h"
class X
{
Y y; // need header for Y
};
Заголовок не требуется:
class Y;
class X
{
Y* y; // don't need header for Y
};
//#include "Y.h" in .cpp file
Второй пример быстрее компилируется и имеет меньше зависимостей. Это может быть важно в больших базовых кодах.
Ответ 5
Заголовочные файлы - это способ разделения интерфейса и реализации. Они делятся на два типа: стандартные и пользовательские файлы заголовков. Стандартный файл заголовка, например string.h, позволяет нам получить доступ к функциям базовой библиотеки C. Вы должны # включить его в каждый .c файл, который использует соответствующую функциональность. Обычно это использует скобки, как в #include Пользовательский заголовочный файл предоставляет вашу реализацию функций другим программистам или другим частям вашего кода C. Если для вычислений с рациональными числами был реализован модуль, называемый rational.c, он должен иметь соответствующий файл rational.h для своего публичного интерфейса. Каждый файл, который использует функциональные возможности, должен #include rational.h, а также rational.c должен # включать его. Обычно это делается с помощью #include "rational.h" Часть компиляции, которая делает #includes, называется препроцессором C. В основном это текстовые замены и пасты. Spence верна в своем шаблоне для предотвращения дублирования #includes, которые испортили пространство имен. Это основа включения, GNU Make дает вам больше мощности, а также больше проблем.
Ответ 6
Просто добавление к Andy Brice отвечает, вы также можете обойтись с объявлениями вперед для возвращаемых значений функции:
class Question;
class Answer;
class UniversityChallenge
{
...
Answer AskQuestion( Question* );
...
};
Здесь ссылка на вопрос, который я задал некоторое время назад с хорошими ответами http://bytes.com/groups/c/606466-forward-declaration-allowed.
Ответ 7
Отъезд обсуждение по использованию #include<filename.h>
и #include<filename>
для С++ включает библиотеки C.
Ответ 8
Вы используете #include "yourfile.h"
, если yourfile.h
находится в текущем рабочем каталоге
и #include <yourfile.h>
, если путь к файлу yourfile.h
был включен в каталоги включений С++ (где-то в конфигурации, например: c:\mylib\yourfile.h
, путь c:\mylib\
должен быть указан как каталог include)
Также вы можете включить .cpp и .hpp(h plus plus).
Существует определенный набор файлов, которые можно записать так: #include <iostream>
. Для этой конкретной работы вам нужно указать using namespace std;
Существует очень приятное программное обеспечение, которое интегрировано с визуальным С++ для Microsoft и показывает пути включения. http://www.profactor.co.uk/includemanager.php
Ответ 9
Редактировать: Энди Брайс также сделал этот шаг более кратким способом.
Следуя за нулевым ответом, самое важное, о чем нужно подумать, - это разместить свой # include.
Когда вы пишете #include, препроцессор буквально включает в себя содержимое файла, который вы перечисляете в текущем файле, включая любые #includes в этих файлах. Это может привести к очень большим файлам во время компиляции (coad bloat), поэтому вам нужно внимательно изучить, если требуется #include.
В стандартном макете кодового файла, где у вас есть .h файл для класса с объявлениями класса и функции, а затем файл реализации .cpp, вы должны быть осторожны с количеством #includes, которые входят в заголовок файл. Это связано с тем, что каждый раз, когда вы вносите изменения в заголовочный файл, все файлы, которые также включают его (то есть, которые используют ваш класс), также должны быть перекомпилированы; если в самом заголовке есть много включений, то каждый файл, который использует класс, значительно раздувается во время компиляции.
Лучше использовать, если это возможно, форвардные объявления, чтобы вы могли писать сигнатуры методов и т.д., а затем # включать соответствующие файлы в .cpp файл, чтобы вы могли фактически использовать классы и структуры, зависящие от вашего кода на.
//In myclass.h
class UtilClass; //Forward declaration of UtilClass - avoids having to #include untilclass.h here
class MyClass
{
MyClass();
~MyClass();
void DoSomethingWithUtils(UtilClass *util); //This will compile due to forward declaration above
};
//Then in the .cpp
#include utilclass.h
void MyClass::DoSomethingWithUtils(UtilClass *util)
{
util->DoSomething(); //This will compile, because the class definition is included locally in this .cpp file.
}