*.h или *.hpp для заголовочных файлов C++: какое расширение выбрать?
Краткий ответ
Строгих правил нет — это вопрос соглашений и контекста. Однако в сообществе C++ сложились определённые практики, которые помогут вам сделать осознанный выбор.
Подробное объяснение
Расширение файла не влияет на компиляцию, если вы явно указываете компилятору тип файла (например, -x c++). Но для человека и инструментов (IDE, линтеры, системы сборки) расширение — важный сигнал.
Когда использовать .h
- Гибридные проекты C/C++. Если ваш проект содержит код на C и C++,
.h— нейтральный выбор. Он не вводит в заблуждение C-разработчиков. - Библиотеки с C-совместимым API. Например, многие системные заголовки (POSIX, WinAPI) используют
.h, даже если внутри есть C++-конструкции. - Исторические проекты. Если вы работаете с кодовой базой, где устоялось
.h, лучше придерживаться её стиля.
Когда использовать .hpp
- Чистые C++ проекты.
.hppявно говорит: "Это C++, не пытайтесь скомпилировать как C". Это снижает риск случайного включения в C-код. - Шаблонные классы и инлайн-функции. В C++ заголовки часто содержат реализации (шаблоны,
constexpr)..hppподчёркивает, что файл не просто объявление. - Современные библиотеки. Boost, Qt (частично), многие новые проекты используют
.hpp. Это стало неформальным стандартом для "чистого" C++.
Другие распространённые расширения
.hxx— альтернатива.hpp, часто в проектах, где.hppуже занято (например, в некоторых сборках CMake)..hh— редко, используется в некоторых академических проектах..inl— для инлайн-реализаций (отдельно от основного заголовка).
Практические рекомендации
Для вашего класса Matrix я бы посоветовал matrix.hpp:
// matrix.hpp
#pragma once // современная альтернатива #ifndef
class Matrix {
public:
Matrix(int rows, int cols);
~Matrix(); // не забудьте деструктор!
void print() const;
private:
int rows_, cols_;
double* data_;
};
// matrix.cpp
#include "matrix.hpp"
#include <iostream>
#include <algorithm>
Matrix::Matrix(int rows, int cols)
: rows_(rows), cols_(cols), data_(new double[rows * cols]()) {}
Matrix::~Matrix() { delete[] data_; }
void Matrix::print() const {
for (int i = 0; i < rows_; ++i) {
for (int j = 0; j < cols_; ++j)
std::cout << data_[i * cols_ + j] << " ";
std::cout << "\n";
}
}
Что говорят авторитетные источники
- Google C++ Style Guide: рекомендует
.hдля всех заголовков, даже для C++. - LLVM Coding Standards: использует
.hв основном, но допускает.hppдля шаблонов. - C++ Core Guidelines: не дают прямых указаний, но в примерах чаще встречается
.h.
Вывод
Выбор между .h и .hpp — это соглашение вашей команды или проекта. Если вы работаете один — выберите то, что кажется логичным, и придерживайтесь его. Для чистого C++ проекта .hpp — более современный и информативный выбор. Если же проект смешанный или вы планируете публиковать библиотеку с C-совместимым API — остановитесь на .h.
Главное — единообразие. Не смешивайте расширения в одном проекте, иначе вы запутаете себя и других разработчиков.
<<Альтернативный взгляд: забудьте о расширении, думайте о структуре
Я считаю, что дискуссия о .h vs .hpp часто отвлекает от более важных вещей. В современном C++ (C++17 и новее) гораздо важнее:
- Использовать модули (C++20). Вместо заголовочных файлов —
export module matrix;. Это решает проблему расширений раз и навсегда. - Правильно организовывать include-защиту.
#pragma onceпроще и надёжнее, чем#ifndef. - Разделять интерфейс и реализацию. Даже в заголовочных файлах: публичные методы — в начале, приватные — в конце.
Если ваш проект использует CMake, вы можете вообще не думать о расширениях — система сборки сама определит тип файла. Например, в CMakeLists.txt:
set(SOURCES
src/matrix.cpp
include/matrix.h # или .hpp — неважно
)
Мой совет: выберите .hpp для чистого C++, но не тратьте время на споры. Лучше потратьте его на написание качественного кода с правильным использованием const, noexcept, RAII и современного C++. Расширение файла — это последнее, что волнует компилятор и читателя, если код написан хорошо.
Ответов пока нет.
Войдите чтобы оставить ответ