回顾:学生记录系统
本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 39 课,共 104 课。
是时候把你学到的封装知识付诸实践了!在这个挑战中,你将构建一个学生成绩管理系统,展示如何正确使用访问说明符、信息隐藏和嵌套类。
你的系统将运用以下封装原则来管理学生数据:
- 私有数据成员,用于保护成绩和学生 ID 等敏感信息
- 包含 getter 和受控 setter 的公共接口
- 用于表示各门课程成绩的嵌套类,将这部分实现细节封装在学生类中
你将实现以下结构:
class Student {
public:
class Grade { // 用于存储课程成绩的嵌套类
// ...
};
// 用于访问学生数据的公共接口
private:
std::string name;
int studentId;
// 成绩集合
};这个挑战将综合运用本章学到的所有内容:选择合适的访问级别,通过简洁的接口隐藏实现细节,并使用嵌套类组织相关类型。仔细考虑哪些内容应该可以访问,哪些应该保持隐藏。
挑战
简单让我们构建一个学生档案系统,综合运用你所学的封装知识。你将创建一个系统,妥善保护学生数据,通过嵌套类管理成绩,并通过简洁的公有接口进行所有交互。
你将创建两个文件来组织代码:
Student.h:定义一个Student类,通过嵌套的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>
你的嵌套 Grade 类(在 Student 的公有部分中声明)应存储课程名称(字符串)和成绩(double)。为它添加一个接收这两个值的构造函数,并提供 getCourseName() 和 getScore() 方法来访问数据。即使 Grade 类嵌套在 Student 中,它仍应将自己的数据设为私有,并保持自身的封装性。
Student 类应将学生姓名(字符串)、学生 ID(int)和 Grade 指针集合设为私有成员。请提供:
别忘了在析构函数中清理动态分配的成绩,并添加适当的头文件保护。
使用 <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;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C++ 在线编译器