Menu
CoddyTech

在线学习平台

本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 103 课,共 104 课。

challenge icon

挑战

简单

让我们来构建一个在线学习平台,把你在本课程中掌握的所有 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 或 nullptr
    • findUser(const std::string& id):返回 shared_ptr 或 nullptr
    • enrollStudent(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 项输入:

    1. 平台名称
    2. 课程详情(格式:title,courseId,instructorId)
    3. 学生详情(格式:name,studentId)
    4. 要添加的课(格式: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++ 在线编译器