- Общая информация
- Расширения файлов
- Header-guard - Неправильный код - Правильный код
- Включение других заголовочных файлов - Неправильный код - Правильный код
- Объявления наперед (forward-declarations)
- Порядок включений
Общая информация
Каждый файл исходного кода (.cc) должен иметь ассоциированный с собой заголовок.
Для этого правила есть исключения, например, в случае с юнит-тестами или файлами с точкой входа в программу (функцией main).
Мы используем для включения только символы <, >. Кавычки не рекомендуются для использования, если в этом нет крайней необходимости.
#include <cat/meow.h> // 😊 правильно
#include "cat/meow.h" // 😡 неправильноРасширения файлов
Заголовочные файлы должны иметь расширение .h. Допускается использования расширения .hh для файлов, не являющихся частью API, то есть не экспортируемых за пределы библиотеки.
Header-guard
Каждый заголовочный файл должен иметь header-guard в виде директивы #pragma once.
Неправильный код
#ifndef MEOW_HEADER
#define MEOW_HEADER
/* ... */
#endif // MEOW_HEADERПравильный код
#pragma once
/* ... */Включение других заголовочных файлов
Если файл использует какой-либо символ из стороннего заголовочного файла, то он должен напрямую включать этот заголовочный файл. Это единственное условие для включения заголовочных файлов и в любом другом случае включение производиться не должно.
Примеры:
Неправильный код
#include <iostream>
std::string a = "qwe";
std::cout << a << std::endl;Данный код может привести к ошибке компиляции на некоторых платформах.
Правильный код
#include <string>
#include <iostream>
std::string a = "qwe";
std::cout << a << std::endl;Объявления наперед (forward-declarations)
Используйте объявления наперед там, где это возможно.
Предупреждение
Не стоит использовать объявления наперед в случае с шаблонными типами и символами из пространства имен
std::.
В случае с заголовочными файлами из стандартной библиотеки поощряется использование стандартных заголовков для объявления наперед, если такие существуют. Например, вместо <iostream> включать <iosfwd> (cppreference).
Порядок включений
Рекомендуется использовать следующий порядок включений:
- Заголовки языка C (
<cstdlib>,<cstring>) - Заголовки стандартной библиотеки C++ (
<iostream>,<string>) - Заголовки ОС (
<unistd.h>,<windows.h>) - Заголовки системных библиотек (
<python.h>,<curl.h>) - Заголовки сторонних библиотек (
<gtest/gtest.h>,<leaf/utils/rtti.h>) - Заголовки Qt. Для заголовков Qt доступны 2 равнозначных стиля включения:
- Включение по полному имени и модулю:
<QtCore/QString>,<QtWidgets/QApplication - Включение по исходному заголовочному файлу:
<qstring.h>,<qobject.h>
- Включение по полному имени и модулю:
- Публичные заголовки текущей библиотеки/проекта:
<cats/meow.h> - Приватные заголовки текущей библиотеки/проекта:
<meow_impl.h> - Условные включения (т.е. обернутые в
#if/#endif)
Пример
#include <cstdlib>
#include <cstdbool>
#include <string>
#include <iostream>
#include <windows.h>
#include <python.h>
#include <gtest/gtest.h>
#include <leaf/leaf.h>
#include <leaf/utils/rtti.h>
#include <qcoreapplication.h>
#include <qobject.h>
#include <qqmlapplicationengine.h>
#include <this_project/cat/meow.h>
#include <this_project/dog/bark.h>
#include <cat/meow_p.h>
#include <dog/bark_p.h>
#if defined(CATS)
# include <this_project/cat/purr.h>
#endifЗамечание
Не допускается использование относительных путей в директиве
#include.