C++ код, который не стыдно показать коллегам: code style и конвенции

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Когда «работает» — это не главное

Представьте ситуацию: вы открываете чужой пул-реквест на C++. Код компилируется, тесты проходят, логика верна. Но вы тратите 40 минут, чтобы понять, что происходит. Переменные названы a, b, ptr2, отступы скачут от 2 до 8 пробелов, а в одном файле смешаны snake_case и camelCase. Знакомо?

В одиночной разработке такой хаос ещё можно пережить. Но как только в проекте появляется второй, третий или десятый разработчик, отсутствие единого code style C++ превращает код в «болото». Каждый пишет так, как привык, а время на код-ревью растёт экспоненциально.

В этой статье мы разберём, какие конвенции C++ реально работают в команде, как их внедрить без боли и почему это сэкономит вам нервы и деньги. Поехали!

Почему code style — это не про «красиво», а про деньги

Многие думают, что споры о стиле кода — это пустая трата времени. На практике исследования (например, от Google и Microsoft) показывают: читаемость кода напрямую влияет на количество багов. Когда разработчик тратит меньше усилий на расшифровку написанного, он реже ошибается при рефакторинге и быстрее находит проблемы.

Единый стандарт кода C++ даёт команде три ключевых преимущества:

  • Скорость онбординга. Новый участник не гадает, как здесь принято писать — он просто смотрит любой файл и видит паттерн.
  • Минимум конфликтов в код-ревью. Вместо «перепиши отступы» вы обсуждаете архитектуру и логику.
  • Автоматизация. Форматтеры и линтеры берут на себя рутину, освобождая мозг для творчества.

Хорошая новость: вам не нужно изобретать велосипед. Существуют проверенные best practices C++, которые адаптируются под любой проект.

Основные конвенции C++: от нейминга до форматирования

Давайте пройдёмся по ключевым блокам, которые стоит зафиксировать в code style guide. Для каждого пункта я приведу пример «плохо» и «хорошо».

1. Именование: snake_case vs CamelCase vs PascalCase

В C++ исторически сложился гибридный подход. Стандартная библиотека использует snake_case, многие компании (Google, Microsoft) тоже предпочитают его для переменных и функций. Для классов и структур чаще берут PascalCase.

Пример плохого нейминга:

class datamanager {
    int numberOfElements;
    void ProcessData(int* ptr) { ... }
};

Проблемы: класс в snake_case, метод в CamelCase, нет контекста. Лучше так:

class DataManager {
    int number_of_elements_;
    void ProcessData(int* data_ptr) { ... }
};

Что здесь исправлено:

  • Класс — PascalCase.
  • Поля — snake_case с суффиксом подчёркивания для приватных членов (стиль Google).
  • Метод — PascalCase (или snake_case, если принято в команде).
  • Параметр — snake_case с суффиксом _ptr, чтобы сразу было ясно, что это указатель.

Совет: выберите один стиль для всего проекта. Смешивание getValue() и get_value() в одном файле — верный путь к путанице.

2. Форматирование: пробелы, скобки и длина строк

Самый частый источник споров — где ставить открывающую скобку: на той же строке или на следующей? В C++ принято ставить её на той же строке (стиль K&R), но есть вариации.

Пример консистентного стиля:

void CalculateSum(const std::vector<int>& values) {
    int sum = 0;
    for (size_t i = 0; i < values.size(); ++i) {
        sum += values[i];
    }
    return sum;
}

Здесь всё единообразно: скобка после if, for, функции — на той же строке. Отступ — 4 пробела (стандарт для большинства C++ проектов). Длина строки — 80–100 символов (чтобы код читался без горизонтального скролла).

Важно: не используйте табуляцию вперемешку с пробелами. Это ломает форматирование в разных редакторах. Либо только табы (редко), либо только пробелы.

3. Комментарии: баланс между избыточностью и тишиной

Хороший код должен быть самодокументируемым. Но это не значит, что комментарии не нужны. Они должны объяснять почему сделано так, а не что делает код (это видно из названий).

Плохо:

// Увеличиваем i на 1
i = i + 1;

Хорошо:

// Индекс сдвигается, потому что первый элемент — заголовок
size_t data_index = header_size + kOffset;

Для документации API используйте Doxygen-стиль:

/**
 * @brief Вычисляет среднее арифметическое вектора.
 * @param data Входные данные (не пустые).
 * @return Среднее значение.
 */
double ComputeAverage(const std::vector<double>& data);

4. Организация файлов: .h vs .cpp, инклюды и неймспейсы

Классическое правило: один класс — один заголовочный файл. Исключения — мелкие вспомогательные структуры или Pimpl-идиома. Инклюды должны быть упорядочены: сначала стандартная библиотека, затем сторонние библиотеки, потом свои заголовки.

Пример правильного порядка:

#include <iostream>
#include <vector>

#include <boost/algorithm/string.hpp>

#include "project/config.h"
#include "project/core/calculator.h"

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

Инструменты, которые автоматизируют code style

Ручные проверки стиля — это прошлый век. Современные инструменты для code style C++ делают 90% работы за вас. Вот три must-have:

Clang-Format

Форматтер, который умеет настраиваться под любой стиль. Создаёте файл .clang-format в корне проекта — и вся команда получает единое форматирование одной командой.

Пример конфига для стиля Google:

BasedOnStyle: Google
IndentWidth:                

Блоги

Рекомендаций по книгам