Перейти к содержимому

Как подключить cpp файл c

  • автор:

Как подключить cpp файл c

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

Например, определим файл sum.cpp , который будет иметь следующий код:

int sum(int a, int b)

Это функция вычисления суммы чисел.

Добавим еще один файл — , который будет содержать объявление функции sum:

int sum(int, int);

И также определим главный файл, который назовем app.cpp :

#include #include "sum.h" // подключаем файл sum.h int main() < int result < sum(5, 4)>; std::cout #include "sum.h"

Файл sum.h еще называется заголовочным файлом (header file), так как содержит объявление, заголовок функции. ПРичем в данном случае предполагается что все файлы располагаются в одном каталоге:

Заголовочные файлы в языке программирования c++

Можно было бы и не подключать файл sum.h и вообще не создавать его, а объявление функции поместить непосредственно в файл app.cpp. Но при изменении функции может потребоваться изменить и ее объявление. И если функция sum используется в нескольких файлах с исходным кодом, то в каждом из этих файлов придется менять ее объявление. В данном же случае достаточно изменить объявление функции в одном файле — sum.h.

При компиляции через g++ необходимо передать все файлы через пробел компилятору:

g++ app.cpp sum.cpp -o app

То же самое верно и для компиляции через Clang::

clang++ app.cpp sum.cpp -o app.exe

На выходе будет сгенерирован единый файл app.

При работе в Visual Studio заголовочные файлы обычны помещаются в каталог «Headers»:

header files в языке программирования c++ в Visual Studio

А при компиляции все файлы автоматически компилируются в один.

Пошаговое руководство. Работа с проектами и решениями (C++)

В этой статье описано, как создать проект C++ в Visual Studio, добавить код, а затем выполнить сборку и запуск проекта. Проект в этом пошаговом руководстве представляет собой программу, которая отслеживает количество игроков в различных карточных играх.

В Visual Studio для организации работы служат проекты и решения. Решение может содержать несколько проектов, например библиотеку DLL и ссылающийся на нее исполняемый файл. Дополнительные сведения см. в статье Solutions and Projects (Решения и проекты).

Перед началом работы

Для выполнения данного пошагового руководства требуется Visual Studio 2017 или более поздней версии. Если вам нужна копия, вот краткое руководство: Установка поддержки С++ в Visual Studio. Если вы еще не сделали этого, выполните приведенные ниже шаги после установки в рамках руководства «Hello, World», чтобы убедиться в правильности установки и работы компонентов C++.

Полезно владеть основами языка C++ и понимать назначение компилятора, компоновщика и отладчика. В руководстве также предполагается, что вы знакомы с Windows и умеете использовать меню и диалоговые окна.

Создание проекта

Чтобы создать проект, сначала выберите шаблон типа проекта. Для каждого типа проекта среда Visual Studio задает параметры компилятора и — в зависимости от типа — создает начальный код, который позже можно изменить. Следующие действия зависят от используемой версии Visual Studio. Чтобы ознакомиться с документацией по предпочтительной версии Visual Studio, используйте селектор Версия. Он находится в верхней части оглавления на этой странице.

Создание проекта в Visual Studio

  1. В главном меню выберите Файл >Создать >Проект, чтобы открыть диалоговое окно Создание проекта.
  2. В верхней части диалогового окна задайте для параметра Язык значение C++, для параметра Платформа значение Windows, а для Типа проектаКонсоль.
  3. В отфильтрованном списке типов проектов щелкните Консольное приложение, а затем нажмите кнопку Далее. На следующей странице введите имя проекта Игра. Вы можете принять расположение по умолчанию в раскрывающемся списке Расположение, ввести другое расположение или нажать кнопку Обзор, чтобы перейти к каталогу, в котором требуется сохранить проект. При создании проекта среда Visual Studio помещает его в решение. По умолчанию имя решения совпадает с именем проекта. Можно изменить имя в поле Имя решения, но для этого примера оставьте имя по умолчанию.
  4. Нажмите кнопку Создать, чтобы создать проект. Visual Studio создает решение и файлы проекта и открывает редактор для созданного файла исходного кода Game.cpp.

Создание проекта в Visual Studio 2017

  1. В строке меню выберите Файл>Создать>Проект.
  2. В левой области диалогового она Новый проект разверните узел Установленные и выберите Visual C++ , если он еще не открыт.
  3. В списке установленных шаблонов в центральной области выберите Консольное приложение.
  4. В поле Имя введите имя проекта. Для этого примера введите Game (Игра). Вы можете принять расположение по умолчанию в раскрывающемся списке Расположение, ввести другое расположение или нажать кнопку Обзор, чтобы перейти к каталогу, в котором требуется сохранить проект. При создании проекта среда Visual Studio помещает его в решение. По умолчанию имя решения совпадает с именем проекта. Можно изменить имя в поле Имя решения, но для этого примера оставьте имя по умолчанию.
  5. Нажмите кнопку ОК, чтобы создать проект. Visual Studio создает решение и файлы проекта и открывает редактор для созданного файла исходного кода Game.cpp.

Создание проекта в Visual Studio 2015

  1. В строке меню выберите Файл>Создать>Проект.
  2. В левой области диалогового она Новый проект разверните узел Установленные и выберите Visual C++ , если он еще не открыт.
  3. В списке установленных шаблонов в центральной области выберите шаблон Консольное приложение Win32.
  4. В поле Имя введите имя проекта. Для этого примера введите Game (Игра). Вы можете принять расположение по умолчанию в раскрывающемся списке Расположение, ввести другое расположение или нажать кнопку Обзор, чтобы перейти к каталогу, в котором требуется сохранить проект. При создании проекта среда Visual Studio помещает его в решение. По умолчанию имя решения совпадает с именем проекта. Можно изменить имя в поле Имя решения, но для этого примера оставьте имя по умолчанию.
  5. Нажмите кнопку ​​ОК, чтобы закрыть диалоговое окно Новый проект, и запустите мастер приложений Win32.
  6. В мастере нажмите кнопку Далее . На странице Параметры приложения в разделе Дополнительные параметрыснимите флажок Предкомпилированный заголовок .
  7. Нажмите кнопку Готово , чтобы создать проект. Visual Studio создает решение и файлы проекта и открывает редактор для созданного файла исходного кода Game.cpp.

Упорядочение файлов и проектов

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

В этой части пошагового руководства описывается добавление класса в проект. При добавлении класса Visual Studio добавляет соответствующие H- и CPP-файлы. Результаты отображаются в обозревателе решений.

Добавление класса в проект

  1. Если окно Обозреватель решений не отображается в Visual Studio, выберите в строке меню Вид>Обозреватель решений.
  2. Выберите проект Game в обозревателе решений. В строке меню выберите Проект>Добавить класс.
  3. В диалоговом окне Добавление класса в поле Имя класса введите значение Cardgame. Не изменяйте имена файлов и параметры по умолчанию. Нажмите кнопку ОК . Visual Studio создает файлы и добавляет их в проект. Вы можете просмотреть их в обозревателе решений. Visual Studio откроет файлы Cardgame.h и Cardgame.cpp в редакторе.
  4. Внесите в файл Cardgame.h следующие изменения.
  5. После открывающей скобки определения класса добавьте два частных элемента данных.
int players; static int totalParticipants; 

После изменения файл Cardgame.h должен выглядеть примерно так:

#pragma once class Cardgame < int players; static int totalParticipants; public: Cardgame(int players); ~Cardgame(); static int GetParticipants() < return totalParticipants; >>; 

Строка #pragma once указывает компилятору включить файл заголовка только один раз. Для получения дополнительной информации см. once . Сведения о других ключевых словах C++ в файле заголовка см. в разделе class , int , static и public .

#include "Cardgame.h" #include using namespace std; int Cardgame::totalParticipants = 0; Cardgame::Cardgame(int players) : players(players) < totalParticipants += players; cout Cardgame::~Cardgame()

Примечание При вводе кода можно использовать автозавершение. Например, при вводе кода с клавиатуры можно ввести pl или tot и нажать клавиши Ctrl+Пробел. Функция автозавершения автоматически вводит players или totalParticipants .

Добавление тестового кода в функцию main

Добавьте в приложение код, тестирующий новые функции.

Добавление тестового кода в проект

  1. В окне редактора Game.cpp замените существующий код следующим:
// Game.cpp : Defines the entry point for the console application. // #include "Cardgame.h" #include using namespace std; void PlayGames() < Cardgame bridge(4); Cardgame blackjack(8); Cardgame solitaire(1); Cardgame poker(5); >int main()

Сборка и запуск проекта приложения

Затем выполните сборку проекта и запустите приложение.

Построение и запуск проекта

  1. В строке меню последовательно выберите Сборка>Собрать решение. Выходные данные сборки выводятся в окне Вывод. Если сборка пройдет успешно, выходные данные должны выглядеть следующим образом:
1>------ Build started: Project: Game, Configuration: Debug Win32 ------ 1>pch.cpp 1>Cardgame.cpp 1>Game.cpp 1>Generating Code. 1>Game.vcxproj -> C:\Users\\source\repos\Game\Debug\Game.exe ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== 
4 players have started a new game. There are now 4 players in total. 8 players have started a new game. There are now 12 players in total. 1 players have started a new game. There are now 13 players in total. 5 players have started a new game. There are now 18 players in total. 

Вы успешно выполнили сборку проекта приложения и решения. Продолжайте выполнять пошаговое руководство, чтобы получить дополнительные сведения о сборке проектов кода C++ в Visual Studio.

Файлы заголовков (C++)

Имена элементов программы, таких как переменные, функции, классы и т. д., должны быть объявлены до их использования. Например, вы не можете просто написать x = 42 без первого объявления "x".

int x; // declaration x = 42; // use x 

Объявление сообщает компилятору, является int ли элемент , функцией double , или class другой вещью. Кроме того, каждое имя должно быть объявлено (прямо или косвенно) в каждом CPP-файле, в котором он используется. При компиляции программы каждый CPP-файл компилируется независимо в единицу компиляции. Компилятор не знает, какие имена объявляются в других единицах компиляции. Это означает, что если вы определяете класс или функцию или глобальную переменную, необходимо указать объявление этой вещи в каждом дополнительном CPP-файле, который использует его. Каждое объявление этой вещи должно быть точно идентичным во всех файлах. Небольшое несоответствие приведет к ошибкам или непреднамеренное поведение, когда компоновщик пытается объединить все единицы компиляции в одну программу.

Чтобы свести к минимуму потенциал ошибок, C++ принял соглашение об использовании файлов заголовков для хранения объявлений. Вы делаете объявления в файле заголовка, а затем используйте директиву #include в каждом CPP-файле или другом файле заголовка, который требует этого объявления. Директива #include вставляет копию файла заголовка непосредственно в CPP-файл перед компиляцией.

В Visual Studio 2019 функция модулей C++20 представлена в качестве улучшения и окончательной замены файлов заголовков . Дополнительные сведения см. в разделе "Общие сведения о модулях в C++".

Пример

В следующем примере показан общий способ объявления класса и его использования в другом исходном файле. Начнем с файла заголовка, my_class.h . Он содержит определение класса, но обратите внимание, что определение является неполным; Функция-член do_something не определена:

// my_class.h namespace N < class my_class < public: void do_something(); >; > 

Затем создайте файл реализации (обычно с расширением CPP или аналогичного расширения). Мы вызовем файл my_class.cpp и предоставим определение для объявления члена. Мы добавим директиву #include для файла "my_class.h", чтобы объявление my_class вставлялось в этот момент в CPP-файле, и мы включаем в объявление. std::cout Обратите внимание, что кавычки используются для файлов заголовков в том же каталоге, что и исходный файл, а для заголовков стандартной библиотеки используются угловые скобки. Кроме того, многие заголовки стандартной библиотеки не имеют расширения H или других файлов.

В файле реализации можно использовать using инструкцию, чтобы избежать необходимости квалифицировать каждую упоминание "my_class" или "cout" с "N::" или "std::". Не помещайте using инструкции в файлы заголовков!

// my_class.cpp #include "my_class.h" // header in local directory #include // header in standard library using namespace N; using namespace std; void my_class::do_something()

Теперь мы можем использовать my_class в другом CPP-файле. Мы #include файл заголовка, чтобы компилятор извлекал объявление. Все, что компилятор должен знать, является то, что my_class является классом, который имеет общедоступную do_something() функцию-член.

// my_program.cpp #include "my_class.h" using namespace N; int main()

После завершения компиляции каждого CPP-файла в OBJ-файлы он передает OBJ-файлы компоновщику. При слиянии компоновщика файлов объектов он находит точно одно определение для my_class; он находится в OBJ-файле, создаваемом для my_class.cpp, и сборка завершается успешно.

Включение охранников

Как правило, файлы заголовков имеют параметр include guard или директиву #pragma once , чтобы убедиться, что они не вставляются несколько раз в один CPP-файл.

// my_class.h #ifndef MY_CLASS_H // include guard #define MY_CLASS_H namespace N < class my_class < public: void do_something(); >; > #endif /* MY_CLASS_H */ 

Что нужно поместить в файл заголовка

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

  • встроенные определения типов в пространстве имен или глобальных область
  • определения функций, отличных от встроенных
  • Определения переменных, отличные от const
  • агрегатные определения
  • безымянные пространства имен
  • Директивы using

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

Пример файла заголовка

В следующем примере показаны различные виды объявлений и определений, которые разрешены в файле заголовка:

// sample.h #pragma once #include // #include directive #include namespace N // namespace declaration < inline namespace P < //. >enum class colors : short < red, blue, purple, azure >; const double PI = 3.14; // const and constexpr definitions constexpr int MeaningOfLife< 42 >; constexpr int get_meaning() < static_assert(MeaningOfLife == 42, "unexpected!"); // static_assert return MeaningOfLife; >using vstr = std::vector; // type alias extern double d; // extern variable #define LOG // macro definition #ifdef LOG // conditional compilation directive void print_to_log(); #endif class my_class // regular class definition, < // but no non-inline function definitions friend class other_class; public: void do_something(); // definition in my_class.cpp inline void put_value(int i) < vals.push_back(i); >// inline OK private: vstr vals; int i; >; struct RGB < short r< 0 >; // member initialization short g< 0 >; short b< 0 >; >; template // template definition class value_store < public: value_store() = default; void write_value(T val) < //. function definition OK in template >private: std::vector vals; >; template // template declaration class value_widget; > 

Подключение cpp файла

Работаю в visual studio. Нашел библиотеку с большими числами:bigint, но не понимаю как ее правильно подключить и использовать. Подскажите, пожалуйста.

Отслеживать
2,419 4 4 золотых знака 20 20 серебряных знаков 37 37 бронзовых знаков
задан 12 фев 2018 в 19:26
635 1 1 золотой знак 10 10 серебряных знаков 28 28 бронзовых знаков
Что документация к библиотеке говорит на этот счет?
12 фев 2018 в 19:37
там ее нет, к сожелению
12 фев 2018 в 19:38

Тогда вам не нужна эта библиотека. OpenSSL содержит те же большие числа, подключается путем добавления lib-файла в опции линкера и каталога инклюдов в опции компилера, например.

12 фев 2018 в 19:40
Для bigint должны быть header-only библиотеки, поищите их.
– user227465
12 фев 2018 в 19:42
header-ов нет, я их искал
12 фев 2018 в 19:45

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Ссылка которую вы дали это не библиотека а просто .cpp файл который должен компилироваться в .exe . Если вы уверены что та структура которая объявлена в этом файле это то что нужно, можно сделать так: Во первых просто скопипастить те функции которые вам нужны к себе в проект. Либо можно создать проект динамической или статической библиотеки, подключить в нее этот файл без функции main . объявления вынести в .h .

Чтобы теперь ей воспользоваться нужно указать в настройках проекта пути до инклюдов, это делается в Configuration properties->C/C++->General->Additional Include Directories. Так же указать линкеру путь до библиотеки это делается в Configuration properties->Linker->General->Additional Library Directories и в Configuration properties->Linker->Input->Additional Dependencies нужно прописать имя библиотеки которую нужно прилинковать.

Отслеживать
ответ дан 13 фев 2018 в 1:44
Rikitikitavi Rikitikitavi
2,419 4 4 золотых знака 20 20 серебряных знаков 37 37 бронзовых знаков

  • c++
  • visual-studio
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.3.2953

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Подключение cpp файла

Работаю в visual studio. Нашел библиотеку с большими числами:bigint, но не понимаю как ее правильно подключить и использовать. Подскажите, пожалуйста.

Отслеживать
2,419 4 4 золотых знака 20 20 серебряных знаков 37 37 бронзовых знаков
задан 12 фев 2018 в 19:26
635 1 1 золотой знак 10 10 серебряных знаков 28 28 бронзовых знаков
Что документация к библиотеке говорит на этот счет?
12 фев 2018 в 19:37
там ее нет, к сожелению
12 фев 2018 в 19:38

Тогда вам не нужна эта библиотека. OpenSSL содержит те же большие числа, подключается путем добавления lib-файла в опции линкера и каталога инклюдов в опции компилера, например.

12 фев 2018 в 19:40
Для bigint должны быть header-only библиотеки, поищите их.
– user227465
12 фев 2018 в 19:42
header-ов нет, я их искал
12 фев 2018 в 19:45

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Ссылка которую вы дали это не библиотека а просто .cpp файл который должен компилироваться в .exe . Если вы уверены что та структура которая объявлена в этом файле это то что нужно, можно сделать так: Во первых просто скопипастить те функции которые вам нужны к себе в проект. Либо можно создать проект динамической или статической библиотеки, подключить в нее этот файл без функции main . объявления вынести в .h .

Чтобы теперь ей воспользоваться нужно указать в настройках проекта пути до инклюдов, это делается в Configuration properties->C/C++->General->Additional Include Directories. Так же указать линкеру путь до библиотеки это делается в Configuration properties->Linker->General->Additional Library Directories и в Configuration properties->Linker->Input->Additional Dependencies нужно прописать имя библиотеки которую нужно прилинковать.

Отслеживать
ответ дан 13 фев 2018 в 1:44
Rikitikitavi Rikitikitavi
2,419 4 4 золотых знака 20 20 серебряных знаков 37 37 бронзовых знаков

  • c++
  • visual-studio
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.3.2953

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Как подключить cpp файл c

Подключаемый файл это файл, содержащий определения функций и переменных, а также макроопределения вместе с некоторыми исходными файлами. Для использования в программе подключаемых файлов применяется директива препроцессора '#include'.

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

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

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

'#include '

Эта модификация используется для подключения системных файлов. При ее выполнении производится поиск файла с именем FILE в списке указанных заранее каталогов, а затем в стандартном списке системных каталогов. С помощью опции '-I' указываются каталоги для поиска подключаемых файлов. Опция '-nostdinc' запрещает поиск в стандартных системных каталогах и производит поиск только в указанных каталогах.

Синтаксис такой модификации директивы '#include' довольно специфичен, потому как комментарии внутри '<. >' не распознаются. Поэтому в строке '#include *y>' последовательность символов '*' не начинает комментарий, а указанная директива включает в программу файл с именем 'x/*y'.

Аргумент FILE не может содержать символа '>', хотя он может содержать символ '

'#include "FILE"'

Эта модификация применяется для подключаемых файлов для программ пользователя. Сначала файл FILE просматривается в текущем каталоге, а затем в каталогах для системных подключаемых файлов. Текущим каталогом является каталог текущего обрабатываемого файла. Он просматривается в первую очередь, так как предполагается, что в нем находятся файлы, имеющие отношение к текущему обрабатываемому файлу. (Если указана опция '-I-', то текущий каталог не просматривается.)

Аргумент FILE не может содержать символов '"'. Символы backslash интерпретируются как отдельные символы, а не начало escape последовательности. Таким образом, директива '#include "x\n\\y"' указывает имя файла, содержащего три символа backslash.

'#include ANYTHING ELSE'

Эта модификация называется "вычисляемой директивой #include". Любая директива '#include', не соответствующая ни одной из модификаций, рассмотреных выше, является вычисляемой директивой. Строка ANYTHING ELSE проверяется на наличие соответствующего макроса, значение которого затем заменяет его название. Полученная в результате строка должна уже в точности соответствовать одной из рассмотренных выше модификаций (то есть имя подключаемого файла должно быть заключено в кавычки или угловые скобки).

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

Директива '#include' указывает С препроцессору обработать указанный файл перед обработкой оставшейся части текущего файла. Информация, выдаваемая препроцессором, содержит уже полученные данные, за которыми следуют данные, получаемые при обработке подключаемого файла, а за которыми, в свою очередь, следуют данные, получаемые при обработке текста, следующего после директивы '#include'. Например, дан следующий подключаемый файл 'header.h':

char *test ();

и основная программа с именем 'program.c', использующая этот файл.
int x; #include "header.h" main ()
Данные, полученные при обработке программы 'program.c' будут выглядеть следующим образом:
int x; char *test (); main ()

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

Подключаемый файл может содержать начало или окончание сиснтаксической конструкции, такой как определение функции.

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

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

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

#ifndef FILE_FOO_SEEN #define FILE_FOO_SEEN Сам файл #endif /* FILE_FOO_SEEN */

Макрос 'FILE_FOO_SEEN' указывает на то, что файл уже однажды вкючался. В подключаемых файлах пользователя макрос не должен начинаться с символа '_'. В системных подключаемых файлах его имя не должно начинаться с символа '__' во избежание возникновения конфликтов с программами пользователя. Каким бы ни был файл, имя макроса должно содержать имя файла и некоторый дополнительный текст во избежание вознкновения конфликтов с другими подключаемыми файлами.

Препроцессор GNU C построен таким образом, что обработке подключаемого файла он проверяет наличие определенных конструкций и наиболее рационально их обрабатывает. Препроцессор специально отмечает полное вложение файла в условие '#ifndef'. Если в подключаемом файле содержится директива '#include', указывающая на обрабатываемый файл, или макрос в директиве '#ifndef' уже определен, то обрабатываемый файл полностью игнорируется.

Существует также специальная директива, указывающая препроцессору, что файл должен быть включен не более одного раза. Эта директива называется '#pragma once'. Она использовалась в дополнение к директиве '#ifndef' и в настоящее время она устарела и не должна прменяться.

В объектно ориентированном языке С существует модификация директивы '#include', называемая '#import', которая используется для вкючения файла не более одного раза. При использовании директивы '#import' вместо '#include' не требуется наличия условных оборотов для предотвращения многократной обработки файла.

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

Если наследуемый подключаемый файл и основной подключаемый файл имеют различные имена, то такое наследование называется прямым. При этом используется конструкция '#include "BASE"' в наследуемом файле.

Иногда необходимо чтобы у наследуемого и основного подключаемого файла были одинаковые имена.

Например, предположим, что прикладная программа использует системный подключаемый файл 'sys/signal.h', но версия файла '/usr/include/sys/signal.h' на данной системе выполняет того, что требуется в прикладной программе. Будет удобнее определить локальную версию, возможно с именем '/usr/local/include/sys/signal.h' для замены или добавления к версии, поставляемой с системой.

Это можно выполнить с применением опции '-I.' при компиляции, а также созданием файла 'sys/signal.h' который выполняет требуемые программе функции. Но сделать так, чтобы этот файл включал стандартный файл 'sys/signal.h' не так просто. При включении строки '#include ' в этот файл произойдет подключение новой версии файла, а не стандартной системной версии. Это приведет к рекурсии и ошибке при компиляции.

При использовании директивы `#include ' нужный файл будет найден, но этот способ является не эфективным, так как содержит полный путь к системному файлу. Это может отразиться на содержании системы, так как это означает, что любые изменения местоположения системных файлов потребуют дополнительных изменений где-либо еще.

Более эффективным решением этой проблемы является применение директивы '#include_next', которая используется для подключения следующего файла с таким же именем. Эта директива функционирует также как и директива '#include' за исключением поиска требуемого файла. Она начинает поиск списка каталогов подключаемых файлов после каталога, где был найден текущий файл.

Предположим была указана опция '-I /usr/local/include', а список каталогов для поиска включает '/usr/include'. Также предположим, что оба каталога содержат файл с именем 'sys/signal.h'. Директива '#include ' найдет нужный файл под каталогом '/usr/local/include'. Если этот файл содержит строку '#include_next ', то поиск будет возобновлен после предыдущего каталога и будет найден файл в каталоге '/usr/include'.

Файлы заголовков (C++)

Имена элементов программы, таких как переменные, функции, классы и т. д., должны быть объявлены до их использования. Например, вы не можете просто написать x = 42 без первого объявления "x".

int x; // declaration x = 42; // use x 

Объявление сообщает компилятору, является int ли элемент , функцией double , или class другой вещью. Кроме того, каждое имя должно быть объявлено (прямо или косвенно) в каждом CPP-файле, в котором он используется. При компиляции программы каждый CPP-файл компилируется независимо в единицу компиляции. Компилятор не знает, какие имена объявляются в других единицах компиляции. Это означает, что если вы определяете класс или функцию или глобальную переменную, необходимо указать объявление этой вещи в каждом дополнительном CPP-файле, который использует его. Каждое объявление этой вещи должно быть точно идентичным во всех файлах. Небольшое несоответствие приведет к ошибкам или непреднамеренное поведение, когда компоновщик пытается объединить все единицы компиляции в одну программу.

Чтобы свести к минимуму потенциал ошибок, C++ принял соглашение об использовании файлов заголовков для хранения объявлений. Вы делаете объявления в файле заголовка, а затем используйте директиву #include в каждом CPP-файле или другом файле заголовка, который требует этого объявления. Директива #include вставляет копию файла заголовка непосредственно в CPP-файл перед компиляцией.

В Visual Studio 2019 функция модулей C++20 представлена в качестве улучшения и окончательной замены файлов заголовков . Дополнительные сведения см. в разделе "Общие сведения о модулях в C++".

Пример

В следующем примере показан общий способ объявления класса и его использования в другом исходном файле. Начнем с файла заголовка, my_class.h . Он содержит определение класса, но обратите внимание, что определение является неполным; Функция-член do_something не определена:

// my_class.h namespace N < class my_class < public: void do_something(); >; > 

Затем создайте файл реализации (обычно с расширением CPP или аналогичного расширения). Мы вызовем файл my_class.cpp и предоставим определение для объявления члена. Мы добавим директиву #include для файла "my_class.h", чтобы объявление my_class вставлялось в этот момент в CPP-файле, и мы включаем в объявление. std::cout Обратите внимание, что кавычки используются для файлов заголовков в том же каталоге, что и исходный файл, а для заголовков стандартной библиотеки используются угловые скобки. Кроме того, многие заголовки стандартной библиотеки не имеют расширения H или других файлов.

В файле реализации можно использовать using инструкцию, чтобы избежать необходимости квалифицировать каждую упоминание "my_class" или "cout" с "N::" или "std::". Не помещайте using инструкции в файлы заголовков!

// my_class.cpp #include "my_class.h" // header in local directory #include // header in standard library using namespace N; using namespace std; void my_class::do_something()

Теперь мы можем использовать my_class в другом CPP-файле. Мы #include файл заголовка, чтобы компилятор извлекал объявление. Все, что компилятор должен знать, является то, что my_class является классом, который имеет общедоступную do_something() функцию-член.

// my_program.cpp #include "my_class.h" using namespace N; int main()

После завершения компиляции каждого CPP-файла в OBJ-файлы он передает OBJ-файлы компоновщику. При слиянии компоновщика файлов объектов он находит точно одно определение для my_class; он находится в OBJ-файле, создаваемом для my_class.cpp, и сборка завершается успешно.

Включение охранников

Как правило, файлы заголовков имеют параметр include guard или директиву #pragma once , чтобы убедиться, что они не вставляются несколько раз в один CPP-файл.

// my_class.h #ifndef MY_CLASS_H // include guard #define MY_CLASS_H namespace N < class my_class < public: void do_something(); >; > #endif /* MY_CLASS_H */ 

Что нужно поместить в файл заголовка

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

  • встроенные определения типов в пространстве имен или глобальных область
  • определения функций, отличных от встроенных
  • Определения переменных, отличные от const
  • агрегатные определения
  • безымянные пространства имен
  • Директивы using

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

Пример файла заголовка

В следующем примере показаны различные виды объявлений и определений, которые разрешены в файле заголовка:

// sample.h #pragma once #include // #include directive #include namespace N // namespace declaration < inline namespace P < //. >enum class colors : short < red, blue, purple, azure >; const double PI = 3.14; // const and constexpr definitions constexpr int MeaningOfLife< 42 >; constexpr int get_meaning() < static_assert(MeaningOfLife == 42, "unexpected!"); // static_assert return MeaningOfLife; >using vstr = std::vector; // type alias extern double d; // extern variable #define LOG // macro definition #ifdef LOG // conditional compilation directive void print_to_log(); #endif class my_class // regular class definition, < // but no non-inline function definitions friend class other_class; public: void do_something(); // definition in my_class.cpp inline void put_value(int i) < vals.push_back(i); >// inline OK private: vstr vals; int i; >; struct RGB < short r< 0 >; // member initialization short g< 0 >; short b< 0 >; >; template // template definition class value_store < public: value_store() = default; void write_value(T val) < //. function definition OK in template >private: std::vector vals; >; template // template declaration class value_widget; > 

Как подключить cpp файл c

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

Например, определим файл sum.cpp , который будет иметь следующий код:

int sum(int a, int b)

Это функция вычисления суммы чисел.

Добавим еще один файл - , который будет содержать объявление функции sum:

int sum(int, int);

И также определим главный файл, который назовем app.cpp :

#include #include "sum.h" // подключаем файл sum.h int main() < int result < sum(5, 4)>; std::cout #include "sum.h"

Файл sum.h еще называется заголовочным файлом (header file), так как содержит объявление, заголовок функции. ПРичем в данном случае предполагается что все файлы располагаются в одном каталоге:

Заголовочные файлы в языке программирования c++

Можно было бы и не подключать файл sum.h и вообще не создавать его, а объявление функции поместить непосредственно в файл app.cpp. Но при изменении функции может потребоваться изменить и ее объявление. И если функция sum используется в нескольких файлах с исходным кодом, то в каждом из этих файлов придется менять ее объявление. В данном же случае достаточно изменить объявление функции в одном файле - sum.h.

При компиляции через g++ необходимо передать все файлы через пробел компилятору:

g++ app.cpp sum.cpp -o app

То же самое верно и для компиляции через Clang::

clang++ app.cpp sum.cpp -o app.exe

На выходе будет сгенерирован единый файл app.

При работе в Visual Studio заголовочные файлы обычны помещаются в каталог "Headers":

header files в языке программирования c++ в Visual Studio

А при компиляции все файлы автоматически компилируются в один.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *