在线学习平台
本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 103 课,共 104 课。
挑战
简单让我们来构建一个在线学习平台,把你在本课程中掌握的所有 OOP 概念结合起来。你将创建一个系统,用于管理课程、不同类型的课,并跟踪学生的学习进度,展示继承层次结构、多态、智能指针和设计模式如何协同工作。
你将把代码分成 6 个文件:
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:使用工厂模式创建不同类型的课。创建一个
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:整合所有内容,展示你的平台。读取 4 项输入:
- 平台名称
- 课程详情(格式:
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这个挑战展示了真实在线学习平台的结构,用户、内容和负责协调它们的平台各自分工明确。工厂模式让课的创建更加灵活,智能指针确保安全管理内存,多态则让你能够统一处理所有类型的课,同时每种课又各有不同的行为。
亲手试试
#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: 输出学生信息和已完成的课数
// 格式:"Completed lessons: [count]"
return 0;
}
面向对象编程中的所有课
自己练习: C++ 在线编译器