Menu
Coddy logo textTech

Recap - Student Records System

Part of the Object Oriented Programming section of Coddy's C++ journey — lesson 39 of 104.

Time to put your encapsulation knowledge into practice! In this challenge, you'll build a Student Records System that demonstrates proper use of access specifiers, information hiding, and nested classes.

Your system will manage student data with these encapsulation principles:

  • Private data members to protect sensitive information like grades and student IDs
  • Public interface with getters and controlled setters
  • A nested class to represent individual course grades, keeping this implementation detail contained within the student class

Here's the structure you'll implement:

class Student {
public:
    class Grade {    // Nested class for course grades
        // ...
    };
    
    // Public interface for interacting with student data
    
private:
    std::string name;
    int studentId;
    // Collection of grades
};

This challenge combines everything from this chapter: choosing appropriate access levels, hiding implementation details behind a clean interface, and using nested classes to organize related types. Think carefully about what should be accessible and what should remain hidden.

challenge icon

Challenge

Easy

Let's build a Student Records System that brings together everything you've learned about encapsulation. You'll create a system where student data is properly protected, grades are managed through a nested class, and all interactions happen through a clean public interface.

You'll create two files to organize your code:

  • Student.h: Define a Student class that demonstrates proper encapsulation with a nested Grade class.

    Your nested Grade class (declared in the public section of Student) should store a course name (string) and a score (double). Give it a constructor that takes both values, and provide getCourseName() and getScore() methods to access the data. The Grade class keeps its data private — even though it's nested inside Student, it still maintains its own encapsulation.

    The Student class should have private members for the student's name (string), student ID (int), and a collection of Grade pointers. Provide:

    • A constructor that takes the name and student ID
    • Getters getName() and getStudentId() (both const)
    • A method addGrade(const std::string& course, double score) that creates a new Grade and adds it to the student's record (only add if score is between 0 and 100 inclusive)
    • A method getAverageGrade() (const) that calculates and returns the average of all grades, or 0.0 if no grades exist
    • A method displayRecord() (const) that shows the student's complete record

    Don't forget to clean up dynamically allocated grades in the destructor, and include proper header guards.

  • main.cpp: Read a student name, student ID, and three course grades from input. The input format will be five lines: name, ID, then three lines each containing a course name and score separated by a space (e.g., Math 95.5).

    Create a Student with the name and ID, add all three grades, then display the complete record.

    The output format for displayRecord() should be:

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

Format all scores and the average with one decimal place using std::fixed and std::setprecision(1) from <iomanip>. Convert the ID using std::stoi() and scores using std::stod().

This challenge combines private data members, public getters, controlled setters with validation, and a nested class — all working together to create a well-encapsulated student records system.

Cheat sheet

Encapsulation combines access specifiers, information hiding, and nested classes to protect data and organize code.

Access Specifiers for Data Protection

Use private for sensitive data members and public for the interface:

class Student {
public:
    // Public interface methods
    
private:
    std::string name;
    int studentId;
    // Other private data
};

Nested Classes

Nested classes organize related types within a class, maintaining their own encapsulation:

class Student {
public:
    class Grade {    // Nested class
    private:
        std::string courseName;
        double score;
    public:
        Grade(const std::string& course, double s) 
            : courseName(course), score(s) {}
        std::string getCourseName() const { return courseName; }
        double getScore() const { return score; }
    };
    
private:
    std::vector<Grade*> grades;
};

Controlled Access with Validation

Methods can validate data before modifying private members:

void addGrade(const std::string& course, double score) {
    if (score >= 0 && score <= 100) {
        grades.push_back(new Grade(course, score));
    }
}

Const Methods

Mark methods that don't modify data as const:

std::string getName() const { return name; }
double getAverageGrade() const {
    // Calculate and return average
}

Memory Management

Clean up dynamically allocated objects in the destructor:

~Student() {
    for (Grade* grade : grades) {
        delete grade;
    }
}

Try it yourself

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

int main() {
    // Read student name
    std::string name;
    std::getline(std::cin, name);
    
    // Read student ID
    std::string idStr;
    std::getline(std::cin, idStr);
    int studentId = std::stoi(idStr);
    
    // Read three course grades (format: "CourseName Score")
    std::string line1, line2, line3;
    std::getline(std::cin, line1);
    std::getline(std::cin, line2);
    std::getline(std::cin, line3);
    
    // TODO: Parse each line to extract course name and score
    // Use std::stod() to convert score strings to doubles
    
    // TODO: Create a Student object with the name and ID
    
    // TODO: Add all three grades to the student
    
    // TODO: Display the complete student record
    
    return 0;
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming