Menu
CoddyTech

回顾:学生记录系统

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

是时候把你学到的封装知识付诸实践了!在这个挑战中,你将构建一个学生成绩管理系统,展示如何正确使用访问说明符、信息隐藏和嵌套类。

你的系统将运用以下封装原则来管理学生数据:

  • 私有数据成员,用于保护成绩和学生 ID 等敏感信息
  • 包含 getter 和受控 setter 的公共接口
  • 用于表示各门课程成绩的嵌套类,将这部分实现细节封装在学生类中

你将实现以下结构:

class Student {
public:
    class Grade {    // 用于存储课程成绩的嵌套类
        // ...
    };
    
    // 用于访问学生数据的公共接口
    
private:
    std::string name;
    int studentId;
    // 成绩集合
};

这个挑战将综合运用本章学到的所有内容:选择合适的访问级别,通过简洁的接口隐藏实现细节,并使用嵌套类组织相关类型。仔细考虑哪些内容应该可以访问,哪些应该保持隐藏。

challenge icon

挑战

简单

让我们构建一个学生档案系统,综合运用你所学的封装知识。你将创建一个系统,妥善保护学生数据,通过嵌套类管理成绩,并通过简洁的公有接口进行所有交互。

你将创建两个文件来组织代码:

  • Student.h:定义一个 Student 类,通过嵌套的 Grade 类展示恰当的封装。
  • 你的嵌套 Grade 类(在 Student 的公有部分中声明)应存储课程名称(字符串)和成绩(double)。为它添加一个接收这两个值的构造函数,并提供 getCourseName() 和 getScore() 方法来访问数据。即使 Grade 类嵌套在 Student 中,它仍应将自己的数据设为私有,并保持自身的封装性。

    Student 类应将学生姓名(字符串)、学生 ID(int)和 Grade 指针集合设为私有成员。请提供:

    • 一个接收姓名和学生 ID 的构造函数
    • Getter:getName() 和 getStudentId()(均为 const)
    • 一个 addGrade(const std::string& course, double score) 方法,用于创建一个新的 Grade 并将其添加到学生档案中(仅当成绩在 0 到 100 之间,且包含 0 和 100 时才添加)
    • 一个 getAverageGrade() 方法(const),用于计算并返回所有成绩的平均值;如果没有成绩,则返回 0.0
    • 一个 displayRecord() 方法(const),用于显示学生的完整档案

    别忘了在析构函数中清理动态分配的成绩,并添加适当的头文件保护。

  • main.cpp:从输入中读取学生姓名、学生 ID 和三门课程的成绩。输入格式为五行:姓名、ID,然后是三行,每行包含课程名称和成绩,两者以空格分隔(例如,Math 95.5)。

    使用姓名和 ID 创建一个 Student,添加三项成绩,然后显示完整档案。

    displayRecord() 的输出格式应为:

    Student: <name> (ID: <id>)
    Grades:
      <course1>: <score1>
      <course2>: <score2>
      <course3>: <score3>
    Average: <average>

使用 <iomanip> 中的 std::fixed 和 std::setprecision(1),将所有成绩和平均值格式化为一位小数。使用 std::stoi() 转换 ID,使用 std::stod() 转换成绩。

这个挑战综合运用了私有数据成员、公有 getter、带验证的受控 setter 和嵌套类,共同构建一个封装良好的学生档案系统。

亲手试试

#include <iostream>
#include <string>
#include <sstream>
#include "Student.h"

int main() {
    // 读取学生姓名
    std::string name;
    std::getline(std::cin, name);
    
    // 读取学生 ID
    std::string idStr;
    std::getline(std::cin, idStr);
    int studentId = std::stoi(idStr);
    
    // 读取三门课程的成绩(格式:"CourseName Score")
    std::string line1, line2, line3;
    std::getline(std::cin, line1);
    std::getline(std::cin, line2);
    std::getline(std::cin, line3);
    
    // TODO: 解析每一行,提取课程名称和分数
    // 使用 std::stod() 将分数字符串转换为 double 类型的值
    
    // TODO: 使用姓名和 ID 创建 Student 对象
    
    // TODO: 将三门课程的成绩添加到学生记录中
    
    // TODO: 显示完整的学生记录
    
    return 0;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C++ 在线编译器