C++

План навчання: Курс C++ — Продовження (Статті 29–60+)

План навчання: Курс C++ — Продовження (Статті 29–60+)

Цей документ є академічним планом розвитку навчального курсу C++ на платформі kostyl.dev. Він описує логічну структуру, тематичний зміст та педагогічні вимоги до кожної статті, яка має бути розроблена після існуючих 28 статей (до теми аргументів командного рядка включно). Стиль викладу — академічний, текстоцентричний («text-first»), з активним використанням компонентів Docus для інтерактивності.


Стан курсу на момент планування

Завершені статті (01–28)

ФайлТема
0101.intro-algorithms.mdВступ до алгоритмів та програмування
0202.code-style.mdСтиль коду та оформлення
0303.ide-setup.mdНалаштування IDE (CLion / VS Code)
0404.data-output.mdВиведення даних (std::cout)
0505.data-types-variables.mdТипи даних та змінні
0606.data-input.mdВведення даних (std::cin)
0707.operators-type-conversion.mdОператори та перетворення типів
0808.loops.mdЦикли (for, while, do-while)
0909.arrays.mdМасиви
1010.sorting.mdАлгоритми сортування
1111.searching.mdАлгоритми пошуку
1212.functions-basics.mdФункції: основи
1313.functions-scope.mdФункції: область видимості
1414.functions-overloading-templates.mdПеревантаження та шаблони функцій
1515.pointers-basics.mdВказівники: основи
1616.references.mdПосилання (references)
1717.pointers-const-arrays.mdВказівники, const та масиви
1818.pointer-arithmetic.mdАрифметика вказівників
1919.dynamic-memory.mdДинамічна пам'ять (new/delete)
2020.void-pointers.mdУзагальнені вказівники (void*)
2121.pointers-to-pointers.mdВказівники на вказівники
2222.member-access-operator.mdОператор доступу до члена (->)
2323.foreach-loop.mdЦикл for на основі діапазону
2424.function-pointers.mdВказівники на функції
2525.lambdas.mdЛямбда-вирази
2626.lambda-captures.mdЗахоплення у лямбда-виразах
2727.ellipsis.mdЕліпсис (...) та варіадичні функції
2828.command-line-arguments.mdАргументи командного рядка

Загальна структура нових модулів

Курс продовжується трьома великими блоками, що логічно виростають із вивченого:

Модуль A: Користувацькі типи даних
  └─ enum, enum class, typedef/using, struct, union

Модуль B: Об'єктно-орієнтоване програмування (ООП)
  └─ Класи, конструктори, деструктори, інкапсуляція,
     спадкування, поліморфізм, абстрактні класи

Модуль C: Стандартна бібліотека та сучасний C++
  └─ std::string, std::vector, std::array, std::map,
     std::optional, smart pointers, move semantics,
     шаблони класів, обробка виключень

Модуль A: Користувацькі типи даних (Статті 29–33)

Логіка модуля

Після опанування функцій, вказівників і лямбда-виразів студент може будувати складні алгоритми, але йому бракує засобів для семантично точного іменування станів і концепцій програми. Цей модуль заповнює прогалину: enum дає назви станам, struct — групує пов'язані дані, а union забезпечує роботу з варіантними даними за умов жорстких обмежень пам'яті.


Стаття 29 — Перерахування (enum)

Файл: 29.enum.mdОрієнтовний обсяг: 2 500–3 500 слів Залежності: 05.data-types-variables.md, 07.operators-type-conversion.md

Навчальні цілі

  • Пояснити мотивацію появи перерахувань: проблема «магічних чисел».
  • Навчити оголошувати та використовувати enum.
  • Показати внутрішнє представлення (int), явне присвоєння значень.
  • Пояснити обмеження «незахищених» (unscoped) перерахувань.
  • Показати практичні патерни: коди помилок, стани стейт-машини.

Структура статті

  1. Вступ і Hook: Сценарій функції readFile(), що повертає -1, -2, -3. Читач бачить код із «магічними числами» і питає: «Що означає -2?» Відповідь — перерахування.
  2. Фундаментальні концепції
    • Визначення: що таке перелічуваний тип (enumerated type).
    • Синтаксис enum, ключове слово, тіло, крапка з комою.
    • Поняття «енумератор» (enumerator) — іменована константа всередині enum.
  3. Механіка та внутрішнє представлення
    • Автоматичне присвоєння цілочисельних значень (з 0).
    • Явне присвоєння значень, від'ємні значення, повторювані значення.
    • Компілятор не перешкоджає дублюванню — чому це небезпечно.
    • Розмір enum в пам'яті (sizeof); зв'язок із int.
    • Компонент ::debugger-view для візуалізації значень.
    • Компонент ::memory-view для демонстрації байтів.
  4. Неявні перетворення та обробка
    • Неявна конвертація enum → int (дозволена).
    • Заборона int → enum без static_cast.
    • Заборона введення через std::cin без tricks.
    • Виведення std::cout — числовий результат, функція printEnum.
  5. Простір імен перерахувань (проблема)
    • Енумератори потрапляють у навколишній простір імен.
    • Конфлікт імен між двома enum в одному файлі.
    • Конвенція іменування PREFIX_VALUE як частковий обхідний шлях.
  6. Практичні патерни
    • Коди повернення функцій замість магічних чисел.
    • Стани кінцевого автомата (стейт-машина гри).
    • Напрямки руху, сторони карти, режими роботи.
    • Компонент ::terminal-preview для демонстрації роботи програм.
  7. Практика та резюме
    • Рівень 1: Оголосити enum Direction з чотирма сторонами; вивести їх значення.
    • Рівень 1: Виправити код із магічними числами за допомогою enum.
    • Рівень 2: Написати функцію getStatusMessage(ParseResult), що повертає рядок.
    • Рівень 2: Реалізувати простий стейт-автомат гравця (стоїть, іде, біжить).
    • Рівень 3: Реалізувати систему статусів HTTP (200, 404, 500) через enum із функцією виводу та обробки помилок.

Стаття 30 — Класи-перерахування (enum class)

Файл: 30.enum-class.mdОрієнтовний обсяг: 2 000–3 000 слів Залежності: 29.enum.md

Навчальні цілі

  • Пояснити недоліки «незахищених» enum: витік у простір імен, неявна конвертація.
  • Ввести enum class (scoped enumeration) як відповідь C++11.
  • Показати синтаксис, область видимості, оператор ::.
  • Розкрити суворі правила типізації: заборона неявних порівнянь різних enum.
  • Навчити явної конвертації через static_cast.
  • Показати задання базового типу (enum class X : uint8_t).

Структура статті

  1. Вступ і Hook: Демонстрація «тихого» баґу — порівняння Fruit::LEMON == Color::PINK проходить компіляцію і повертає true. Чому? Обидва мають значення 0. Це реальна помилка, яку важко знайти. Рішення — enum class.
  2. Фундаментальні концепції
    • Поняття «scoped» vs «unscoped» перерахування.
    • Синтаксис enum class (або enum struct — синоніми).
    • Оператор розширення імені (scope resolution operator ::) для доступу.
  3. Суворі правила типізації
    • Неявна конвертація enum class → int заборонена.
    • Порівняння двох різних enum class заборонене.
    • Порівняння всередині одного enum class — дозволене.
    • Приклад помилки компіляції та її пояснення.
  4. Явна конвертація
    • static_cast<int>(value) — коли і навіщо.
    • static_cast<MyEnum>(intVal) — небезпека, UB (Undefined Behavior).
    • Патерн безпечної конвертації через std::underlying_type_t.
  5. Задання базового типу
    • Синтаксис enum class Direction : uint8_t { ... }.
    • Навіщо: економія пам'яті у вбудованих системах, мережеві протоколи.
    • sizeof порівняння.
  6. enum class у switch-statement
    • Синтаксис switch(dir) із case Direction::North:.
    • Попередження компілятора про неповний switch.
    • Патерн з default та [[fallthrough]].
  7. Порівняльна таблиця: enum vs enum class
    Властивістьenumenum class
    Область видимостіГлобальнаЛокальна
    Неявна конвертація в int
    Порівняння різних типів✅ (баґ!)❌ (захист)
    Задання базового типуЧастково
    Рекомендованість у C++11+
  8. Практика та резюме
    • Рівень 1: Переписати enum із попередньої статті на enum class; виправити звернення.
    • Рівень 1: Написати switch для виведення назви дня тижня.
    • Рівень 2: Реалізувати enum class Permission : uint8_t (Read/Write/Execute) та функцію перевірки прав доступу.
    • Рівень 3: Реалізувати міні-парсер HTTP відповідей: enum class HttpStatus : uint16_t з категоризацією (isSuccess(), isRedirect(), isError()).

Стаття 31 — Псевдоніми типів (typedef і using)

Файл: 31.type-aliases.mdОрієнтовний обсяг: 2 000–2 800 слів Залежності: 05.data-types-variables.md, 14.functions-overloading-templates.md

Навчальні цілі

  • Пояснити призначення typedef: читабельність, підтримка, кросплатформність.
  • Навчити синтаксису typedef oldType newName.
  • Ввести using newName = oldType (C++11) як переважний синтаксис.
  • Показати застосування для спрощення складних типів (вказівники на функції).
  • Пояснити стандартні псевдоніми (int8_t, uint32_t тощо).

Структура статті

  1. Вступ і Hook: Функція, що приймає std::vector<std::pair<std::string, int>> тричі в прототипі. Читач відчуває біль. Рішення — один псевдонім.
  2. typedef: синтаксис та семантика
    • typedef double seconds_t; — базовий патерн.
    • Суфікс _t як конвенція.
    • typedef не створює новий тип, лише псевдонім.
    • Порядок: спочатку існуючий тип, потім нове ім'я.
  3. Чотири причини використання typedef
    • Читабельність: testScore_t GradeTest() проти int GradeTest().
    • Підтримка: зміна базового типу в одному місці.
    • Кросплатформність: int8_t, int16_t, uint32_t з <cstdint>.
    • Спрощення: складні типи (std::map<std::string, std::vector<int>>).
  4. typedef і вказівники на функції
    • Проблема: bool (*compare)(int, int) — незрозумілий синтаксис.
    • Рішення: typedef bool (*Comparator)(int, int);.
    • Зв'язок із попередньою статтею про вказівники на функції.
  5. using — сучасний синтаксис (C++11)
    • using seconds_t = double; — еквівалент typedef.
    • Чому using кращий: читабельніший порядок (псевдонім = тип).
    • using для шаблонних псевдонімів (template aliases) — перевага перед typedef.
  6. Стандартні типи з <cstdint>
    ТипРозмірЗнакОпис
    int8_t8 бітЗі знакомМалий цілий
    uint8_t8 бітБез знакуБайт
    int16_t16 бітЗі знакомКороткий цілий
    uint32_t32 бітБез знакуНатуральний
    int64_t64 бітЗі знакомВеликий цілий
    ptrdiff_tЗі знакомРізниця вказівників
    size_tБез знакуРозміри об'єктів
  7. Поширені помилки та анти-патерни
    • Надмірне використання псевдонімів: коли це шкодить читабельності.
    • typedef в заголовковому файлі — правила включення.
    • typedef у глобальному просторі імен — ризики забруднення.
  8. Практика та резюме
    • Рівень 1: Створити using Meters = double; using Seconds = double;; написати функцію швидкості.
    • Рівень 1: Замінити всі int у масиві ідентифікаторів на using StudentID = uint32_t.
    • Рівень 2: Спростити вказівник на функцію з попередніх статей через using.
    • Рівень 3: Розробити «шар абстракції платформи» — оголосити набір using-псевдонімів, що перемикаються за допомогою #ifdef між int32_t і int64_t.

Стаття 32 — Структури (struct)

Файл: 32.struct.mdОрієнтовний обсяг: 3 500–5 000 слів Залежності: 05.data-types-variables.md, 15.pointers-basics.md, 19.dynamic-memory.md

Навчальні цілі

  • Пояснити потребу в агрегуванні даних: проблема «Координата з трьох змінних».
  • Навчити оголошувати struct, ініціалізувати агрегатно.
  • Пояснити доступ до членів (. та ->).
  • Показати передачу структур у функції (за значенням vs за посиланням).
  • Ввести поняття вкладених структур та масивів структур.
  • Показати struct з методами (bridge до ООП).

Структура статті

  1. Вступ і Hook: Студент реалізує студента через string name; int age; double gpa;. Три окремі змінні для одного поняття. Передати в функцію — три параметри. Масив студентів — три масиви. Рішення — struct.
  2. Фундаментальні концепції
    • Визначення: структура як агрегатний тип даних (aggregate type).
    • Синтаксис оголошення struct, члени-дані (data members), крапка з комою після }.
    • Різниця між оголошенням типу і визначенням змінної.
  3. Ініціалізація та агрегатна ініціалізація
    • Агрегатна ініціалізація: Student s = {"Alice", 20, 3.9}.
    • Ініціалізація за ім'ям члена (C++20 designated initializers): Student s = {.name = "Alice"}.
    • Значення за замовчуванням у членах (default member initializers).
    • Часткова ініціалізація — що отримує неініціалізований член.
  4. Доступ до членів
    • Оператор . для об'єктів і посилань.
    • Оператор -> для вказівників (повторення з 22.member-access-operator.md).
    • ::debugger-view для візуалізації стану структури.
  5. Структури та пам'ять
    • Розмір структури (sizeof) та вирівнювання (alignment, padding).
    • Візуалізація через ::memory-view.
    • __attribute__((packed)) — коли і чому небезпечно.
  6. Передача у функції
    • Передача за значенням: копія, витрати на копіювання.
    • Передача за константним посиланням const Student&: рекомендований патерн.
    • Передача за вказівником: коли доречно.
    • Повернення структури з функції, NRVO (Named Return Value Optimization).
  7. Масиви структур та вкладені структури
    • Student class_students[30]; — масив структур.
    • Вкладена структура: Address всередині Student.
    • Цикл for-each по масиву структур.
  8. Структури з методами (перехідний місток до ООП)
    • Функція-член всередині struct (void print() const { ... }).
    • Структура з конструктором (попередній перегляд).
    • Різниця struct та class у C++ (лише за замовчуванням видимості).
  9. Практика та резюме
    • Рівень 1: Оголосити struct Point3D {double x, y, z;}; написати функцію відстані.
    • Рівень 1: Ініціалізувати масив Color[8] та вивести таблицю RGB значень.
    • Рівень 2: Реалізувати struct Matrix2x2 з операціями множення.
    • Рівень 2: Написати struct LinkedListNode з вказівником на наступний вузол.
    • Рівень 3: Реалізувати систему обліку студентів: struct Student, struct Course, функції пошуку, сортування та виведення звіту.

Стаття 33 — Об'єднання (union)

Файл: 33.union.mdОрієнтовний обсяг: 2 000–2 800 слів Залежності: 32.struct.md, 05.data-types-variables.md

Навчальні цілі

  • Пояснити семантику union: один блок пам'яті, кілька інтерпретацій.
  • Показати, коли union корисний: мережеві пакети, варіантні типи, рендерери.
  • Пояснити UB при зчитуванні не-активного члена.
  • Ввести std::variant (C++17) як безпечну альтернативу.

Структура статті

  1. Вступ і Hook: Уявімо сенсор, що може повертати або float, або статус uint32_t. Як зберегти обидва варіанти без зайвих байтів?
  2. Фундаментальні концепції
    • Синтаксис union, розмір дорівнює розміру найбільшого члена.
    • Активний член (active member): зміна одного членa змінює інтерпретацію пам'яті.
    • ::memory-view для демонстрації перекриття байтів.
  3. Практичні застосування
    • Мережеві пакети: доступ до байтів uint32_t IP адреса як uint8_t[4].
    • Floating-point хаки: читання бітів float через uint32_t.
    • Анонімні union у структурах.
  4. Undefined Behavior та правила
    • Зчитування не-активного члена: UB у C++, але «common initial sequence» виключення.
    • union з нетривіальними типами (конструктор/деструктор) — складнощі.
  5. std::variant як сучасна альтернатива
    • Синтаксис std::variant<int, float, std::string>.
    • std::get<> та std::visit.
    • Чому перевагу надають variant у сучасному коді.
  6. Практика та резюме
    • Рівень 1: Оголосити union Data з int i, float f; вивести їх байтові представлення.
    • Рівень 2: Реалізувати union IPv4 для зберігання IP-адреси як числа та байтів.
    • Рівень 3: Реалізувати std::variant-based систему повідомлень для простого сокет-протоколу.