Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Оглавление курса по C++ #158

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

Microvenator
Copy link
Contributor

@Microvenator Microvenator commented Nov 26, 2024

Обсуждаем содержимое курса по C++. Проекты для практики будут добавлены после устаканивания порядка глав.

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

cpp/contents.md Outdated Show resolved Hide resolved
cpp/contents.md Outdated Show resolved Hide resolved
cpp/contents.md Outdated Show resolved Hide resolved
cpp/contents.md Show resolved Hide resolved
cpp/contents.md Outdated Show resolved Hide resolved
cpp/contents.md Outdated Show resolved Hide resolved
cpp/contents.md Outdated
- Неявное преобразование и explicit
- Правило 3 (5)
- Спецификаторы =default, =delete
- Использование std::move(), std::forward()
Copy link

@Nomlsbad Nomlsbad Nov 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::move и особенно std::forward странно рассматривать до rvalue, lvalue, прочих value и шаблонов.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отрефакторено в спираль.

Теперь такой подход:

  1. RAII. Владение ресурсом.
  2. В некоторых случаях неплохо бы передавать владение. А не копировать и не пробрасывать ссылку.
  3. std::move() - взгляд пользователя. Решаем с помощью std::move() конкретные практические задачи.
  4. rvalue ссылки
  5. Реализация копирования и перемещения в собственных классах
  6. Постигаются шаблоны в достаточной степени, чтобы прийти к...
  7. Perfect forwarding!

Мне этот подход кажется самым жизненным и практико-ориентированным. И последовательным.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если интересно, то вот как мув-семантику объясняют другие. У каждого свой подход) План трех хороших лекций:

HSE C++ Advanced 2024 Lectures (Move семантика)

  1. Каждое выражение характеризуется типом и категорией
  2. Категории: lvalue, xvalue, prvalue, ...
  3. Примеры категорий с пояснениями: (a, b) = 5;
  4. lvalue ссылки
  5. Примеры ссылок
  6. Константную ссылку можно привязать к rvalue
  7. Идиома swap+clear (как жили до появления мув-семантики в С++11)
  8. Чем плох auto_ptr и за что он был выпнут из стандарта: в конструкторе копирования исходный указатель обнуляется. Это неочевидное поведение, ибо все остальные конструкторы копирования не меняют исходный объект.
  9. Почему такое поведение auto_ptr было необходимо.
  10. Затрака про rvalue ссылки и мув-семантику
  11. Самостоятельное изобретение мув-семантики для auto_ptr. Получается рабочий, но страшненький вариант.
  12. ...А вот если бы обладали властью над синтаксисом языка, мы могли бы сделать красиво.
  13. Приходим к && и std::move(). На этом месте всем становится ясно, что std::move() ничего не мувает)
  14. Правило трех -> правило пяти / правило нуля.
  15. Разбираются примеры объявления rvalue ссылок.
  16. На семинарах обещается разобрать perfect forwarding, std::forward().

Константин Владимиров. Базовый курс C++ (MIPT, ILab). Lecture 5. RAII и перемещение

  1. Что такое владение ресурсом
  2. Примеры освобождения ресурсов: в разных ветках кода, в Си-стиле через goto, goto-маскирующая конструкция do-while(0), linux kernel кодинг стайл: может быть несколько меток для goto
  3. Чем плох goto. Другие goto-маскирующие конструкции: switch-case, break, continue, return
  4. Освобождение ресурса в деструкторах: RAII
  5. Класс ScopedPointer, который освобождает ресурс в деструкторе. Конструктор от сырого указателя. Разбор, чем ScopedPointer плох: при копировании ScopedPointer получается shallow copy. Как написать копирование и присваивание, как не дать утечь указателю? Как сделать доступ к состоянию?
  6. Глубокое копирование
  7. Оператор *() - dereference. Оператор ->()
  8. Чем ScopedPointer опять плох? Получили слишком много выделений памяти при свопе ScopedPointer. Подводка к семантике перемещения: в языке не хватает механизма, чтобы сделать RAII эффективными.
  9. Что такое lvalue, lvalue ссылки. rvalue
  10. Семантика перемещения и rvalue ссылки
  11. Что такое std::move()
  12. Кросс-связывание: rvalue ссылка не может быть связана с lvalue, неконстантная lvalue ссылка не может быть связана с rvalue, сама по себе rvalue ссылка задает имя и адрес и является lvalue
  13. Методы на rvalues. Аннотации методов через & и &&
  14. Проблемы при возвращении rvalue ссылок
  15. Перемещающие конструкторы и операторы. Выгода при глубоком копировании
  16. Перемещающее присваивание. Как делать правильно: оставляем правую часть в консистентном (инварианты класса не нарушены), но не обязательно предсказуемом состоянии
  17. Эффективный обмен значениями. Как swap() был реализован до С++11, как - после
  18. Как не убивать RVO злоупотреблениями std::move
  19. Особенности std::move(). Что будет при муве инта. Перемещение по умолчанию перемещает по умолчанию все поля класса
  20. Правило пяти и правило нуля

Илья Мещерин. Лекторий ФПМИ. C++ 27. move-семантика, move-конструкторы

  1. Описание проблемы: несколько примеров кода с лишним копированием. Например, vec.emplace_back(3, "some_str")
  2. std::move - взгляд со стороны пользователя
  3. используем семантику && в move-конструкторах и перемещающих операторах присваивания. Пока не вдаемся в подробности, что это такое. Просто юзаем.
  4. В каких случаях какие конструкторы и операторы надо определять, а в каких они создаются компилятором
  5. std::swap для пользовательского класса с мув-конструктором
  6. Свой push_back, проблема с emplace_back и обобщением копирующего/перемещающего push_back в своем классе строка
  7. Правило пяти - если есть нетривиальное что-то из этого, то нужно определить все
  8. Виды value
  9. Правила инициализации ссылок
  10. Универсальные ссылки
  11. Реализация std::move
  12. Проблема унификации push_back
  13. swap и универсальные ссылки
  14. std::forward
  15. emplace_back, push_back и std::forward
  16. std::forward от rvalue
  17. xvalue
  18. temporary materialization
  19. reference qualifiers

cpp/contents.md Outdated Show resolved Hide resolved
cpp/contents.md Outdated
- ...макросы

# Сборка проекта
- Организация проекта

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут можно поговорить про различные варианты организации проектов, от "плоской", до сложных типа pitchfork: http://www.max-sperling.bplaced.net/?p=10296 или организации библиотек по типу супер проекта (boost, Qt)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Знать, какие удобные варианты раскладки проекта выработало сообщество и самому не ломать над этим голову - это полезно.

Не менее полезно знать modern cmake. И хорошие практики для работы с Conan, vcpkg и т.д. И вообще уметь в "инфраструктуру вокруг языка".

К чему я веду) Материала, касающегося непосредственно C++, очень и очень много. Уже сейчас количество глав подходит к 50. Это опасно: чем более раздутый курс, тем больший процент студентов его забросит. Мы должны уметь вовремя останавливаться.

Какие у нас есть варианты:

  1. Выносим пункт "Автоматизация сборки" из этой главы в отдельную. И в ней на примере нескольких раскладок проекта (плоская, pitchfork и тд) показываем, что из себя представляет modern cmake.
  2. В пункт "Организация проекта" добавляем буквально пару фраз про то, что вариантов организации проектов масса, но вот есть такая, такая и такая. Со ссылками на гитхаб, чтобы студент мог на примере живого проекта познакомиться с вариантом организации.
  3. Для инфраструктурных приседаний вокруг C++ напрашивается отдельный курс. Но у нас нет автора.

Кто что думает?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не смог удержаться и пройти мимо.
Поддерживаю. Cmake кмк сильнее всех распространен, но это целый отдельный мир и более того, это один из вариантов, увы. Хотелось бы конечно что-то одно, а у нас:

  • configure && make/nmake
  • cmake
  • bazel
  • ?
    И сами эти системы тянут на отдельный курс.
    Имхо, для знакомства с языком эти системы могут быть пропущены, потому что вызвать компилятор для 2-3 единиц трансляции не сложно, а в рамках курса я не думаю что будет полезно делать больше. Например при объяснении линковки или типов либ, объяснить как скомпилить либу и как ее линкануть. Тут не тот масштаб, когда надо браться за систему сборки.

Если по курсу планируется привязка к ОС, то можно минимально подцепить Makefile, ибо это приятный бонус. Годится не только для C++)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отрефакторено в спираль)

Copy link

@umedjankabiri umedjankabiri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@Microvenator
Copy link
Contributor Author

Microvenator commented Nov 29, 2024

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

Фичи плюсовые давать исходя из практики с одной стороны (в начале научиться пользоваться алгоритмами и контейнерами например), с другой стороны по спирали, то есть в начале можно дать на самом поверхностном уровне, потом погружение глубже.

@BeardedBeaver

Я согласен с замечанием про спиральную структуру. сейчас почти вся информация по одной теме собрана в один блок, от базовой до продвинутой, это может быть сложно для понимания.
Возможно лучше давать информацию слоями.
Например gdb я бы показал близко к началу, а вот вальгринды и асаны уже в конце.
int и char это база, а decltype можно отложить на потом

Можно попробовать выделить в текущем оглавлении "продвинутые" пункты и убрать их все кучей вниз во второй круг ада. Дальше подтюнить порядок глав на переходе от простого блока к сложному чтобы логика выдерживалась. Дальше помедитировать на результат и по необходимости выдернуть набор тем в блок средней сложности

@Reavolt кажется, это ты говорил:

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

@khva

Мне идея спирали не очень нравится. И вот почему:

  1. Сложно реализовать. Сложно разделить большинство тем на несколько уровней. (Можно внимательней посмотреть продвинутый курс лекций Владимирова, он использует слоенный подход в рамках одной лекции. И попытаться подчерпнуть принцип.)
  2. Спиральный курс нельзя использовать в качестве справочника.
  3. Не надоест ли изучающему читать про лямбды (к примеру) в третий раз?

Мне больше по душе 2-х уровневый подход:

  1. Поверхностное освещение самых необходимых элементов языка, чтобы изучающий мог быстро начать программировать на языке.
  2. Детальное изучение каждой темы. (Хотя в случае плюсов детальное рассмотрение любой темы легко превращается в небольшую книгу, а иногда и большую :D)

В частности на основе 4-ой главы можно сделать небольшую выжимку, в которой рассказать про построение проекта, используя gcc и CMake. А 4-ую главу передвинуть в конец.

cpp/contents.md Outdated
- Перегрузка функций
- inline

# Что такое UB
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Чтобы добить оставшихся, можно ещё пару слов об IF и IFNDR написать.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, это вещь. Пришлось добавить)

@Microvenator
Copy link
Contributor Author

@umedjankabiri @Nomlsbad @mrmomenticus @Reavolt @khva @leha-bot @Intey

Гайз, содержание курса отрефакторено для спиральной подачи материала. Между некоторыми главами добавлены проекты для практики. Гляньте пожалуйста и покритикуйте.

@Reavolt
Copy link

Reavolt commented Dec 4, 2024

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

Упоминание ссылок и указателей можно отложить до обсуждения "RAII и управления памятью".

Стандартные контейнеры и алгоритмы
Я бы этот блок переместил ближе к разделу "Типы данных", чтобы дать больше инструментов для работы с данными до перехода к более сложным концепциям.
Контейнеры могут быть структурированы по сложности: начать с вектор, массивы, потом переходить к ассоциативным контейнерам.

# Классы: основы
- Поля и методы
- Спецификаторы доступа protected, public, private
- friend
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На будущее, возможно пригодится в мотивации, зачем нам нужен это самый friend.

Мне нравится пример, где может быть удобен friend - тестирование с помощью gtest.
В их гайде, есть ответ на вопрос "как тестировать приватную часть класса?". И там они советуют в целевой (тестируемый) класс добавить friend GTestMyTestCaseName (имя класса генерируется макросом) и вуаля, в тесте можем творить бесчинства.
Тут холеварный момент - "а надо ли тестировать через приватную часть?", но как минимум, можно в тестах упростить проверку на ожидаемое состояние класса.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, френдить тестовые классы - классический пример из реальной жизни. У него есть и плюсы, и минусы. Обязательно их перечислим.

@Microvenator
Copy link
Contributor Author

@Reavolt

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

Этот пункт главы будет совсем маленьким. Он сводится к перечислению баззвордов с кратким описанием. Это важно, потому что пользователь так или иначе будет что-то дополнительно искать и читать. Его жизнь будет проще, если он к тому моменту ухватит основные баззворды и будет в теме, что такое stl, boost, gtest и т.д.

Упоминание ссылок и указателей можно отложить до обсуждения "RAII и управления памятью".

В задачах часто придется передавать в функцию объекты по константным ссылкам. Чтобы для пользователя это не было черной магией, кажется, про ссылки нужно поговорить пораньше. Полноценная глава про указатели будет сильно дальше. А до нее - просто краткое упоминание.

Стандартные контейнеры и алгоритмы Я бы этот блок переместил ближе к разделу "Типы данных", чтобы дать больше инструментов для работы с данными до перехода к более сложным концепциям.

Можешь пожалуйста предложить конкретный вариант разбиения на главы этого куска курса? Попробовала сделать что-то такое, но получилась дичь из чередования ифов, строк, циклов, векторов и тд. С какой-то стороны это хорошо. Потому что несколько глав подряд учить контейнеры - скучно. Но выглядит такое оглавление как поток сознания. В общем, покажи, как ты это видишь)

Контейнеры могут быть структурированы по сложности: начать с вектор, массивы, потом переходить к ассоциативным контейнерам.

На данный момент же так и есть? Сначала массивы, потом списки, мапы и тд.

- Адресная арифметика
- Массивы
- Управление ресурсами, new/delete vs memalloc/free
- Идиома pimpl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

оно разве связано с указателями? больше же про компоновку проекта и "что в хедере писать, а что в cpp". Может нужна отдельная глава, про "зачем вообще хедеры и почему без них никак"? Там же можно глубже ковырнуть в ELF (или аналог на винде), про то, как исполняемый находит библиотеки и как это изменить?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

оно разве связано с указателями? больше же про компоновку проекта и "что в хедере писать, а что в cpp"

Эта штука затрагивает две темы. Она о том, чтобы в хедере объявить нужный класс, через forward-declaration объявить внутренний класс, и в нужном классе сделать поле - указатель на объект этого внутреннего класса. Определение которого будет в cpp.

Так как про хедеры и cpp уже есть в главах "Базовые концепции", "Как собрать и запустить простой проект", то к этой главе пользователь будет хорошо подготовлен.

Может нужна отдельная глава, про "зачем вообще хедеры и почему без них никак"?

Это будет в "Базовые концепции", "Как собрать и запустить простой проект". "без них никак" - ну, это уже не совсем так. Появились же модули. И про них кстати тоже будет.

Там же можно глубже ковырнуть в ELF (или аналог на винде), про то, как исполняемый находит библиотеки и как это изменить?

Это уедет в "Подкапотная магия компилятора". Возможно, эта глава будет переименована, потому что в ней будет и про детали сборки.

@Microvenator Microvenator changed the title C++ course contents draft Оглавление курса по C++ Jan 3, 2025
- noexcept

# Классы: основы
- Поля и методы
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не нашёл нигде ничего про указатели на поля и методы классов.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Докинули! a12a3fe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants