Платформа для онлайн-обучения
Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy. Урок 103 из 104.
Задание
ЛегкоДавайте создадим платформу электронного обучения, которая объединит все концепции ООП, освоенные вами на протяжении этого курса. Вы создадите систему, управляющую курсами и различными типами уроков, а также отслеживающую прогресс студентов: продемонстрируете совместную работу иерархий наследования, полиморфизма, умных указателей и шаблонов проектирования.
Вы организуете код в шести файлах:
User.h: Создайте иерархию пользователей с базовым классомUserи двумя производными классами:StudentиInstructor.Ваш базовый класс
Userдолжен иметь имя и ID, виртуальный методgetRole(), возвращающий тип пользователя в виде строки, и методgetInfo(), возвращающий"[name] ([id]) - [role]".Класс
Studentотслеживает ID зачисленных курсов (используйте вектор строк) и количество завершённых уроков. Добавьте методыenrollInCourse(const std::string& courseId),completedLesson()для увеличения счётчика иgetCompletedCount().Класс
Instructorхранит строку со специализацией и отслеживает ID преподаваемых им курсов. ДобавьтеaddCourse(const std::string& courseId)иgetSpecialty().Lesson.h: Создайте иерархию уроков с использованием абстрактного базового класса.Ваш базовый класс
Lessonдолжен иметь заголовок и продолжительность (в минутах), чистый виртуальный методcomplete(), возвращающий сообщение о завершении, и методgetType(), возвращающий тип урока.Создайте три производных класса:
VideoLesson: содержит URL видео. Его методcomplete()возвращает"Watched video: [title]"QuizLesson: содержит количество вопросов. Его методcomplete()возвращает"Completed quiz: [title] ([questions] questions)"TextLesson: содержит количество слов. Его методcomplete()возвращает"Read article: [title]"
Каждый из них должен переопределять
getType(), возвращая соответственно"Video","Quiz"или"Text".Course.h: Создайте классCourse, который владеет своими уроками с использованием умных указателей.Курс имеет заголовок, ID и ID инструктора. Храните уроки как
std::vector<std::unique_ptr<Lesson>>, поскольку курс владеет своими уроками единолично.Добавьте методы:
addLesson(std::unique_ptr<Lesson> lesson): передаёт владение уроком курсуgetLessonCount(): возвращает количество уроковgetLesson(size_t index): возвращает указатель на урок с указанным индексом (или nullptr, если индекс недействителен)displayCurriculum(): выводит тип и заголовок каждого урока в формате"[index]. [Type]: [title]"
LessonFactory.h: Реализуйте шаблон Factory для создания различных типов уроков.Создайте класс
LessonFactoryсо статическим методомcreateLesson(const std::string& type, const std::string& title, int duration, const std::string& extra), который возвращаетstd::unique_ptr<Lesson>.Параметр
typeопределяет, какой урок создать ("video","quiz"или"text"). Параметрextraсодержит данные, зависящие от типа: URL для видео, количество вопросов для викторины (преобразуйте в int) или количество слов для текста (преобразуйте в int).Platform.h: Создайте центральный классPlatform, координирующий всю работу.Храните курсы как
std::vector<std::shared_ptr<Course>>, а пользователей — какstd::vector<std::shared_ptr<User>>.Реализуйте:
addCourse(std::shared_ptr<Course> course)addUser(std::shared_ptr<User> user)findCourse(const std::string& id): возвращает shared_ptr или nullptrfindUser(const std::string& id): возвращает shared_ptr или nullptrenrollStudent(const std::string& studentId, const std::string& courseId): находит обоих, зачисляет студента и выводит"Enrolled [name] in [course title]"или"Enrollment failed"completeLesson(const std::string& studentId, const std::string& courseId, size_t lessonIndex): находит студента и курс, вызывает метод complete() урока, увеличивает счётчик завершённых уроков студента и выводит сообщение о завершении или"Could not complete lesson"
main.cpp: Объедините всё, чтобы продемонстрировать работу платформы.Считайте четыре входных значения:
- Название платформы
- Данные курса (формат:
title,courseId,instructorId) - Данные студента (формат:
name,studentId) - Добавляемый урок (формат:
type,title,duration,extra)
Создайте платформу и выведите
"Welcome to [platform name]!". Создайте курс и студента, добавьте их на платформу. Используйте LessonFactory для создания урока и добавьте его в курс. Выведите учебный план курса. Зачислите студента на курс. Завершите первый урок (индекс 0) для этого студента. Наконец, выведите информацию о студенте и количество завершённых им уроков в виде"Completed lessons: [count]".
Например, для входных данных CodeAcademy, C++ Mastery,CPP101,I001, Alice,S001 и video,Introduction to OOP,30,https://example.com/oop:
Welcome to CodeAcademy!
1. Video: Introduction to OOP
Enrolled Alice in C++ Mastery
Watched video: Introduction to OOP
Alice (S001) - Student
Completed lessons: 1Для входных данных LearnHub, Python Basics,PY100,I002, Bob,S002 и quiz,Variables Quiz,15,10:
Welcome to LearnHub!
1. Quiz: Variables Quiz
Enrolled Bob in Python Basics
Completed quiz: Variables Quiz (10 questions)
Bob (S002) - Student
Completed lessons: 1Этот вызов демонстрирует структуру реальных платформ электронного обучения с чётким разделением пользователей, контента и платформы, которая их координирует. Шаблон Factory делает создание уроков гибким, умные указатели обеспечивают безопасное управление памятью, а полиморфизм позволяет единообразно работать со всеми типами уроков, сохраняя уникальное поведение каждого из них.
Попробуйте сами
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "User.h"
#include "Lesson.h"
#include "Course.h"
#include "LessonFactory.h"
#include "Platform.h"
int main() {
// Читать входные данные
std::string platformName;
std::getline(std::cin, platformName);
std::string courseDetails; // формат: title,courseId,instructorId
std::getline(std::cin, courseDetails);
std::string studentDetails; // формат: name,studentId
std::getline(std::cin, studentDetails);
std::string lessonDetails; // формат: type,title,duration,extra
std::getline(std::cin, lessonDetails);
// TODO: Разобрать courseDetails, чтобы извлечь title, courseId, instructorId
// TODO: Разобрать studentDetails, чтобы извлечь name, studentId
// TODO: Разобрать lessonDetails, чтобы извлечь type, title, duration, extra
// TODO: Создать платформу и отобразить "Welcome to [platform name]!"
// TODO: Создать курс и студента, добавить их на платформу
// TODO: Использовать LessonFactory для создания урока и добавления его в курс
// TODO: Отобразить учебный план курса
// TODO: Записать студента на курс
// TODO: Завершите первый урок (индекс 0) для студента
// TODO: Print the student's info and completed lesson count
// Format: "Completed lessons: [count]"
return 0;
}
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыСборка и компиляция C++Заголовочные файлы и файлы исходного кодаПространства имен и область видимостиВведение в ООП на C++Классы и объектыУказатель 'this'Методы (функции-члены)Атрибуты (члены данных)Основы конструкторов и деструкторовИтоги — Простой калькулятор4Свойства классов
Члены экземпляра против статическихГеттеры и сеттерыКонстантные функции-членыКлючевое слово mutableСтатические методы и переменныеДружественные функции и классыИтоги — Менеджер банковских счетов7Наследование
Основы наследованияУровни доступа при наследованииПорядок вызова конструкторов и деструкторовПереопределение методовВиртуальные функции и VTableМножественное наследованиеВиртуальное наследованиеИтоги — Иерархия сотрудников10Обзор STL
Обзор и философия STLКонтейнеры STLИтераторыАлгоритмы STLФункторы и лямбда-выраженияИтоги: частота слов13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonFactory и Abstract FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy2Управление памятью
Стек и кучаУказатели и ссылкиДинамическая память (new/delete)Умные указатели в C++RAII в C++Итоги — Менеджер динамического массива5Инкапсуляция
Спецификаторы доступа в C++Спецификаторы доступа: подробный разборСокрытие данныхStruct против ClassВложенные и внутренние классыИтоги — Система учета студентов8Полиморфизм
Полиморфизм компиляции и времени выполненияПерегрузка функцийВиртуальные функции: повторениеЧистые виртуальные функцииАбстрактные классыПроектирование интерфейсов на C++Dynamic Casting и RTTIИтоги: Калькулятор фигур11Продвинутые концепции ООП
Композиция против наследованияМиксины через CRTPИдиома PimplСтирание типовEnum Classes и строгая типизацияОбработка исключений в ООППользовательские иерархии исключений14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикRAII как паттерн3Конструкторы и деструкторы
Конструктор по умолчаниюПараметризованный конструкторКонструктор копированияКонструктор перемещенияСписки инициализации конструктораДелегирующие конструкторыГлубокое погружение в деструкторыПравило трех / пяти / нуляПовторение — класс String6Перегрузка операторов
Введение в перегрузку операторовПерегрузка арифметических операторовПерегрузка операторов сравненияОператоры потоковПерегрузка оператора присваиванияПерегрузка операторов [] и ()Операторы преобразования типовИтоги — класс Matrix9Шаблоны
Шаблоны функцийШаблоны классовСпециализация шаблоновВариативные шаблоныОсновы SFINAE и Type TraitsИтоги — Обобщенный контейнерПотренируйтесь самостоятельно: Онлайн-компилятор C++