סיכום – מערכת רשומות תלמידים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C++ של Coddy. שיעור 39 מתוך 104.
הגיע הזמן ליישם את הידע שלך בכימוס! באתגר הזה תבנה מערכת לרישומי תלמידים שמדגימה שימוש נכון במפרטי גישה, הסתרת מידע ומחלקות מקוננות.
המערכת שלך תנהל נתוני תלמידים באמצעות עקרונות הכימוס האלה:
- חברי נתונים פרטיים להגנה על מידע רגיש כמו ציונים ומספרי זיהוי של תלמידים
- ממשק ציבורי עם פונקציות לקבלת ערכים ופונקציות מוגדרות לשינוי שלהם
- מחלקה מקוננת לייצוג ציונים בקורסים בודדים, כך שפרט המימוש הזה יישאר בתוך מחלקת התלמיד
זו התבנית שתממש:
class Student {
public:
class Grade { // מחלקה מקוננת לציוני קורסים
// ...
};
// ממשק ציבורי לעבודה עם נתוני הסטודנט
private:
std::string name;
int studentId;
// אוסף ציונים
};האתגר הזה משלב את כל מה שנלמד בפרק הזה: בחירת רמות גישה מתאימות, הסתרת פרטי המימוש מאחורי ממשק נקי ושימוש במחלקות מקוננות לארגון טיפוסים קשורים. חשוב היטב למה צריכה להיות גישה ומה צריך להישאר מוסתר.
אתגר
קלבואו נבנה מערכת לרישום פרטי תלמידים שמאגדת את כל מה שלמדת על כימוס. תיצור מערכת שבה נתוני התלמידים מוגנים כראוי, הציונים מנוהלים באמצעות מחלקה מקוננת, וכל האינטראקציות מתבצעות דרך ממשק ציבורי ברור.
תיצור שני קבצים כדי לארגן את הקוד שלך:
Student.h: הגדר מחלקהStudentשמדגימה כימוס תקין באמצעות מחלקה מקוננתGrade.המחלקה המקוננת
Gradeשלך (שמוצהרת באזור הציבורי שלStudent) צריכה לאחסן שם של קורס (מחרוזת) וציון (double). תן לה בנאי שמקבל את שני הערכים, וספק את המתודותgetCourseName()ו-getScore()כדי לגשת לנתונים. מחלקתGradeשומרת את הנתונים שלה פרטיים; גם כשהיא מקוננת בתוךStudent, היא עדיין שומרת על הכימוס שלה.למחלקה
Studentצריכים להיות איברים פרטיים עבור שם התלמיד (מחרוזת), מספר התלמיד (int) ואוסף של מצביעים מסוגGrade. ספק:- בנאי שמקבל את השם ואת מספר התלמיד
- פעולות גישה
getName()ו-getStudentId()(שתיהן const) - מתודה
addGrade(const std::string& course, double score)שיוצרתGradeחדשה ומוסיפה אותה לרשומת התלמיד (יש להוסיף רק אם הציון בין 0 ל-100, כולל) - מתודה
getAverageGrade()(const) שמחשבת ומחזירה את ממוצע כל הציונים, או 0.0 אם אין ציונים - מתודה
displayRecord()(const) שמציגה את הרשומה המלאה של התלמיד
אל תשכח לשחרר את הציונים שהוקצו דינמית בתוך ההורס, ולהוסיף שומרי כותרת מתאימים.
main.cpp: קרא מהקלט שם של תלמיד, מספר תלמיד ושלושה ציונים בקורסים. פורמט הקלט יהיה חמש שורות: שם, מספר, ואז שלוש שורות שכל אחת מהן מכילה שם של קורס וציון המופרדים ברווח (למשל,Math 95.5).צור
Studentעם השם ומספר התלמיד, הוסף את שלושת הציונים, ואז הצג את הרשומה המלאה.פורמט הפלט של
displayRecord()צריך להיות:Student: <name> (ID: <id>) Grades: <course1>: <score1> <course2>: <score2> <course3>: <score3> Average: <average>
עצב את כל הציונים ואת הממוצע עם ספרה אחת אחרי הנקודה העשרונית באמצעות std::fixed ו-std::setprecision(1) מתוך <iomanip>. המר את מספר התלמיד באמצעות std::stoi() ואת הציונים באמצעות std::stod().
האתגר הזה משלב איברי נתונים פרטיים, פעולות גישה ציבוריות, פעולות עדכון מבוקרות עם אימות ומחלקה מקוננת: כולם פועלים יחד כדי ליצור מערכת לרישום פרטי תלמידים שכמוסה היטב.
נסו בעצמכם
#include <iostream>
#include <string>
#include <sstream>
#include "Student.h"
int main() {
// קרא את שם הסטודנט
std::string name;
std::getline(std::cin, name);
// קרא את מזהה הסטודנט
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: צור אובייקט Student עם השם והמזהה
// TODO: הוסף את כל שלושת הציונים לסטודנט
// TODO: הצג את הרשומה המלאה של הסטודנט
return 0;
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות OOP
קבצים חיצונייםבנייה וקומפילציה של C++קובצי Header וקובצי מקורמרחבי שמות והיקףמבוא ל-OOP ב-C++מחלקות לעומת אובייקטיםמצביע thisמתודות (פונקציות איבר)תכונות (חברי נתונים)יסודות הבנאים וההורסיםסיכום – מחשבון פשוט4מאפייני מחלקה
חברי מופע לעומת חברים סטטייםגטרים וסטריםפונקציות איבר קבועותמילת המפתח mutableמתודות ומשתנים סטטייםפונקציות ומחלקות ידידותסיכום – מנהל חשבונות בנק7ירושה
ירושה בסיסיתרמות גישה בירושהסדר הקריאות לבנאי ולמפרקדריסת מתודותפונקציות וירטואליות ו־VTableירושה מרובהירושה וירטואליתסיכום – היררכיית עובדים2ניהול זיכרון
זיכרון Stack לעומת Heapמצביעים והפניותזיכרון דינמי (new/delete)מצביעים חכמים ב-C++RAII ב-C++סיכום – מנהל מערכים דינמיים5כימוס
מצייני גישה ב-C++מצייני גישה לעומקהסתרת מידעמבנה לעומת מחלקהמחלקות מקוננות ופנימיותסיכום – מערכת רשומות תלמידים8רב־צורתיות
רב־צורתיות בזמן קומפילציה לעומת בזמן ריצההעמסת פונקציותפונקציות וירטואליות — מבט נוסףפונקציות וירטואליות טהורותמחלקות מופשטותתכנון ממשקים ב־C++המרה דינמית ו־RTTIסיכום — מחשבון צורות3בנאים והורסים
בנאי ברירת מחדלבנאי עם פרמטריםבנאי העתקהבנאי העברהרשימות אתחול בבנאיםבנאים מאציליםמעמיקים בנושא הורסיםכלל השלושה / החמישה / האפססיכום – מחלקת String6העמסת אופרטורים
מבוא להעמסת אופרטוריםהעמסת אופרטורים אריתמטייםהעמסת אופרטורי השוואהאופרטורי זרםהעמסת אופרטור השמההעמסת האופרטורים [] ו־()אופרטורים להמרת טיפוסיםסיכום – מחלקת Matrix9תבניות
תבניות פונקציהתבניות מחלקההתמחות תבניותתבניות ארגומנטים משתנותיסודות SFINAE ותכונות טיפוסיםסיכום – מכל גנריתרגלו בעצמכם: קומפיילר C++ אונליין