Programming Fundamentals Using C++

Project 04 · Student Record Management System

Modules 14–16 (Weeks 14–16) · the first class with a stated invariant — private state, guarded mutators, file round-trip Outcomes: CLO-7, CLO-8 (PF-14…PF-16). Difficulty: ★★★★☆ · Builds on P3.

1. Problem description

A department office keeps student records: id, name, program, and a GPA that must always lie in 0.00..4.00, plus a status that only moves in one direction (active → graduated) — never backward. P3 kept books, which can be anything; a student record carries rules. Those rules must be enforced by the type itself, not by hoping every caller remembers them. Build a small system whose core is one class with real invariants and a menu that cannot break them.

2. Learning objectives

  1. Design a class: private data, public interface, stated invariants.
  2. Write guarded mutators that make invalid states unreachable.
  3. Use const member functions for observers; keep I/O out of the class.
  4. Round-trip a class-managed collection through a text file.
  5. Report from an invariant-safe collection without re-validating.

3. Functional requirements

4. Non-functional requirements

5. Suggested data structures

6. User interaction design

loaded: 3 skipped: 0
menu (add|gpa|graduate|find|report|quit): gpa S-1001 9.0
rejected
menu (add|gpa|graduate|find|report|quit): gpa S-1001 3.4
ok
menu (add|gpa|graduate|find|report|quit): graduate S-1001
ok
menu (add|gpa|graduate|find|report|quit): graduate S-1001
already graduated
menu (add|gpa|graduate|find|report|quit): report
students: 3 graduated: 1 gpa-mean: 2.93
cs: 1 ds: 1 se: 1
menu (add|gpa|graduate|find|report|quit): quit
saved: 3

7. Input validation requirements

8. Testing plan

#ClassScenarioExpected
T1invariantgpa 4.00 then 4.01first ok, second rejected
T2invariantgpa 0.00 acceptedok (boundary is inclusive)
T3invariantgraduate twiceok then already graduated
T4invariantduplicate idduplicate id, count unchanged
T5round-trip3 records, quit, restartloaded: 3 skipped: 0
T6poisoned filefile with gpa 9.0 lineskipped: 1 — invariant holds from birth
T7report policy1 graduated (gpa 4.0) + 2 active (3.0, 3.5)mean 3.25 over ACTIVE only; graduated count 1
T8bad programadd S-1010 Xx mathbad program
T9observer-onlyattempt: does any public path write name/gpa directly?code review: none exists
T10write-protectread-only dir on quitcannot save, exit 2

9. Milestones

  1. M1: Student class + invariants + unit-style demo main (no menu, no file) exercising T1–T3.
  2. M2: Roster + menu add/gpa/graduate + T4, T8.
  3. M3: file round-trip + poisoned-file rejection + T5, T6, T10.
  4. M4: report (per-program counts, active-only mean) + T7 + rubric pass.

10. Extension ideas ⚙

11. Assessment rubric (10 points when graded as homework)

PointsLine
0–3Class design: private state, guarded mutators, const observers, invariants stated (T1–T3, T9)
0–2Roster invariants: unique ids, program whitelist (T4, T8)
0–2File round-trip + poisoned-line rejection (T5, T6)
0–2Report policies exact (active-only mean, counts) (T7)
0–1I/O out of the classes (NFR2) + test table

Course-gate: does not compile with the contract → 0.

12. Student instructions

Work individually (pair by arrangement). Write the invariant comment FIRST — the rubric grades whether the code makes the invariant unbreakable, not whether the menu "mostly works". Deliberate attack pass: try to break your own invariant through every public path; document each attempt in postmortem.md (successful defenses count as your defect narrative). Deliverables: records.cpp, test_table.md (T1–T10), postmortem.md (≥ 1 defect narrative + the attack log), sample roster.txt. Zip as p04_<yourid>.zip.

Programming Fundamentals Using C++ · C++17 · 16 weeksBack to top ↑