В C++ те се наричат още хедър файлове, което идва от английски (header files). Това са файлове с разширение .h или .hpp. Тяхното използване идва от езика C. И обратната съвместимост на C++ към него. Понякога ги наричаме просто заглавки.
В езика C++ се разделя декларацията от имплементацията. Декларацията се прави в хедър файловете. А имплементацията, описанието на кода в съответния .cpp файл със същото име както .h файла.
Какво има в хедър файла:
- декларации на функции;
- декларации на класове и структури;
- декларации на константи и променливи;
- декларации на макроси;
Какво има в .cpp файла:
В съответния .cpp файл се имплементират функциите и другите работи описани в хедър файла със същото име. Там може да има и помощни функции и данни. Но те не са видим извън съответния файл.
Разделяне на декларациите и имплементацията
Нека дадем пример. Нека направим следното: Да напишем програма, която приема две int числа от потребителя. После тя ще отпечата сбора на тези числа и техния най – малък общ делител. Това е кратък и ясен пример. Но функционалността ще я изведем от главната програма в MathCalls.h и MathCalls.cpp
MathCalls.h (декларациите)
// MathCalls.h
#ifndef MathCalls_h
#define MathCalls_h
// сума на две числа
int Sum(int x, int y);
// най - малък общ делител
int LCM(int x, int y);
#endif /* MathCalls_h */Това са декларациите на функциите, които реализират нашата функционалност. Тези функции са видими навсякъде където добавим нашата заглавка така:
#include "MathCalls.h"Моля обърнете внимание на кавичките. Всеки заглавен файл дефиниран от потребителя (от вас) се пише в кавички. Заглавните файлове от библиотеката на C++ се заградени с ‘<‘ и ‘>. Както досега винаги пишехме <iostream> или <string>.
Include guards
Има и друго на което трябва да обърнем внимание. От горния пример редовете: 2,3 и 11 съдържат макроси на пред процесора. Те ни предпазват от грешки. Помислете, какво би станало ако напишете два пъти: #include „MathCalls.h“ ?
- #ifndef MathCalls_h Проверява, дали символа MathCalls_h е дефиниран. Тоест дали вече хедъра е инклуднат;
- #define MathCalls_h Ако символа не е дефиниран добавя цялото съдържание до #endif в текущия .cpp файл; Тоест изпълнява се #include „MathCalls.h“;
- #endif /* MathCalls_h */ Това означава край на макроса;
Така че без значение дали имате инклудване MathCalls.h няколко пъти (а това може да дойде от друг хедър, който също използва MathCalls.h) в текущия ви .cpp файл ще се добави само това:
// сума на две числа
int Sum(int x, int y);
// най - малък общ делител
int LCM(int x, int y);MathCalls.cpp (дефиницийте)
#include "MathCalls.h"
// помощнта функция
// не се вижда в другите файлове
// най - голям общ делител
// (алгоритъм на Евклид)
int GCD(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
// НОК
// най - малък общ делител
int LCM(int a, int b) {
return (a / GCD(a, b)) * b;
}
int Sum(int x, int y) {
return x + y;
}Да съберем всичко в едно
След като вече дефинирахме функционалността, която искаме трябва да приложим всичко в една изпълнима програма. Създайте нов проект в средата за разработка, която ползвате. Това ще ви генерира и файл с името main.cpp където е и главната функция на програмата. Добавите хедър и .cpp фаловете които описахме към проекта си.
main.cpp
#include <iostream>
#include <string>
#include "MathCalls.h"
using namespace std;
int ReadInt(string prompt) {
prompt += "= ";
cout << prompt;
int x;
cin >> x;
return x;
}
int main() {
int x = ReadInt("X");
int y = ReadInt("Y");
cout << "Sum= " << Sum(x, y) << endl;
cout << "LCM= " << LCM(x, y) << endl;
}Ето и вероятен изход на терминала от изпълнението на тази програма:
X= 3
Y= 2
Sum= 5
LCM= 6Какво прави компилатора на C++ тук?
Първо нека да уточним, че това е пример за проект с множество файлове. За компилатора main.cpp и MathCalls.cpp са два отделни обекта за компилация. Те се наричат „единици за компилация„.
Хедър файловете не се компилират отделно. Те заедно с Include guards служат за правилното разпределение на декларациите в отделните .cpp файлове. Хедър файловете се „разширяват“ и стават част от всяка компилационна единица.
Компилатора компилира всеки .cpp файл отделно и генерира обектен код: .obj или .o фаил. Накрая свързващата програма наречена linker ги обединява в един изпълним файл.

Често срещани грешки
- ❌ Multiple definition: функция дефинирана в повече от един .cpp файл;
- ❌ Undefined reference: декларация има, но няма реализация;
- ❌ Липсващ include: компилаторът не знае за дадена функция;