Раздел справочника

C++

C++ — компилируемый язык общего назначения с поддержкой процедурного, объектно-ориентированного, обобщённого и метапрограммирования. Этот раздел собирает краткие справочные материалы по синтаксису, объектной модели, времени жизни объектов, шаблонам, стандартной библиотеке и современным возможностям языка.

Обзор

Что важно понимать в C++

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

Ключевая идея: хороший C++-код обычно не содержит ручных пар new/delete в бизнес-логике. Владение ресурсами выражается через объекты: std::vector, std::string, std::unique_ptr, std::shared_ptr, файловые и сетевые обёртки.

Zero-cost abstractions

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

Value semantics

Значения можно копировать, перемещать, хранить в контейнерах, передавать по ссылке или владению. Это влияет на API и стоимость операций.

Undefined behavior

Некоторые ошибки не обязаны диагностироваться: выход за границы, use-after-free, нарушение strict aliasing и гонки данных приводят к неопределённому поведению.

Language

Конструкции языка

Object model

Объектная модель

Объект в C++ имеет тип, область хранения, время жизни, адрес и набор допустимых операций. Для классов дополнительно важны специальные функции-члены: конструктор по умолчанию, копирующий конструктор, move-конструктор, операторы присваивания и деструктор.

Правило
Смысл
Когда применять
Rule of Zero
Не объявлять специальные функции вручную, если класс сам не владеет ресурсом.
Предпочтительный вариант для большинства классов.
Rule of Three
Если нужен деструктор, обычно нужны копирующий конструктор и copy assignment.
Старый стиль C++ до move-семантики.
Rule of Five
Добавляет move-конструктор и move assignment к Rule of Three.
Классы, которые напрямую владеют ресурсом.
class Buffer {
public:
    Buffer() = default;

    explicit Buffer(std::size_t size)
        : data_(size) {}

    std::size_t size() const noexcept {
        return data_.size();
    }

private:
    std::vector<std::byte> data_;
};

Этот класс следует Rule of Zero: он не управляет памятью вручную, а делегирует владение контейнеру std::vector.

Memory

Память и время жизни

Ошибки времени жизни — одна из главных причин сложных дефектов в C++. Нужно различать область видимости имени, область хранения объекта и фактическое время жизни объекта.

Automatic storage

Локальные объекты обычно создаются при входе в блок и уничтожаются при выходе из блока.

Dynamic storage

Объекты создаются в динамической памяти. В современном C++ прямой new обычно заменяется на контейнеры и smart pointers.

Static storage

Объекты существуют в течение всей программы. Сюда относятся глобальные переменные и статические локальные объекты.

Thread storage

Объекты с thread_local имеют отдельный экземпляр для каждого потока.

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

Templates

Шаблоны и обобщённое программирование

Шаблоны позволяют писать код, параметризованный типами, значениями и другими шаблонами. Они используются в контейнерах, алгоритмах, type traits, smart pointers и compile-time вычислениях.

template <typename T>
T max_value(const T& a, const T& b) {
    return b < a ? a : b;
}

Function templates

Шаблоны функций позволяют обобщить алгоритм для разных типов.

Class templates

Шаблоны классов лежат в основе контейнеров вроде std::vector<T>.

Concepts

Начиная с C++20, constraints позволяют явно описывать требования к типам.

Standard library

Стандартная библиотека C++

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

Standards

Стандарты C++

Стандарт
Ключевые возможности
Использование
C++11
auto, nullptr, move-семантика, lambda, constexpr, thread library.
Базовый современный C++.
C++14
Улучшенный constexpr, generic lambdas, make_unique.
Небольшое, но удобное развитие C++11.
C++17
structured bindings, if constexpr, filesystem, optional, variant.
Частый промышленный минимум.
C++20
concepts, ranges, coroutines, modules, spaceship operator.
Современный стиль API и generic-кода.
C++23
Расширения ranges, std::expected, std::print, улучшения constexpr.
Постепенно появляется в новых проектах.

Examples

Небольшие примеры

RAII и автоматическое освобождение

#include <fstream>
#include <string>

std::string read_first_line(const char* path) {
    std::ifstream file(path);

    std::string line;
    std::getline(file, line);

    return line;
}

Поток std::ifstream закрывает файл в деструкторе. Ручной вызов close() обычно не нужен.

Передача владения

#include <memory>

struct Connection {
    void send(const char* data);
};

void use(std::unique_ptr<Connection> conn) {
    conn->send("ping");
}

auto conn = std::make_unique<Connection>();
use(std::move(conn));

std::unique_ptr нельзя копировать, но можно перемещать. Так API явно показывает передачу владения.