مراجعة - نظام سجلات الطلاب
جزء من قسم البرمجة كائنية التوجه في رحلة C++ على Coddy. الدرس 39 من 104.
حان الوقت لتطبيق معرفتك بالتغليف عمليًا! في هذا التحدي، ستبني نظام سجلات الطلاب يوضّح الاستخدام السليم لمحدّدات الوصول، وإخفاء المعلومات، والفئات المتداخلة.
سيدير نظامك بيانات الطلاب باستخدام مبادئ التغليف التالية:
- أعضاء بيانات خاصة لحماية المعلومات الحساسة مثل الدرجات ومعرّفات الطلاب
- واجهة عامة تتضمن دوال الحصول ومُعيّنات مضبوطة
- فئة متداخلة لتمثيل درجات المقررات الفردية، مع إبقاء هذه التفاصيل التنفيذية محصورة داخل فئة الطالب
إليك البنية التي ستنفّذها:
class Student {
public:
class Grade { // فئة متداخلة لدرجات المقررات
// ...
};
// واجهة عامة للتفاعل مع بيانات الطالب
private:
std::string name;
int studentId;
// مجموعة من الدرجات
};يجمع هذا التحدي كل ما ورد في هذا الفصل: اختيار مستويات الوصول المناسبة، وإخفاء تفاصيل التنفيذ خلف واجهة واضحة، واستخدام الفئات المتداخلة لتنظيم الأنواع المرتبطة. فكّر مليًا في ما ينبغي أن يكون متاحًا وما ينبغي أن يظل مخفيًا.
التحدي
سهللنَبْنِ نظامًا لسجلات Student يجمع كل ما تعلمته عن التغليف. ستنشئ نظامًا تكون فيه بيانات الطلاب محمية بشكل صحيح، وتتم إدارة الدرجات من خلال فئة متداخلة، وتحدث جميع التفاعلات عبر واجهة عامة نظيفة.
ستنشئ ملفين لتنظيم التعليمات البرمجية:
Student.h: عرّف فئةStudentتوضّح التغليف الصحيح باستخدام فئةGradeمتداخلة.يجب أن تخزّن فئة
Gradeالمتداخلة (المُعلنة في القسم العام منStudent) اسم المقرر (سلسلة نصية) والدرجة (عددًا عشريًا). امنحها مُنشئًا يأخذ القيمتين، ووفّر طريقتيgetCourseName()وgetScore()للوصول إلى البيانات. تحافظ فئةGradeعلى خصوصية بياناتها؛ وعلى الرغم من أنها متداخلة داخلStudent، فإنها تظل تحافظ على تغليفها الخاص.يجب أن تحتوي فئة
Studentعلى أعضاء خاصة لاسم الطالب (سلسلة نصية)، ومعرّف الطالب (عدد صحيح)، وcollectionمن مؤشراتGrade. وفّر ما يلي:- مُنشئًا يأخذ الاسم ومعرّف الطالب
- دالتي Getter هما
getName()وgetStudentId()(وكلاهما const) - طريقة
addGrade(const std::string& course, double score)تنشئ كائنGradeجديدًا وتضيفه إلى سجل الطالب (أضِف فقط إذا كانت الدرجةbetween0 و100 شاملًا) - طريقة
getAverageGrade()(const) تحسب متوسط جميع الدرجات وتُعيده، أو تعيد 0.0 إذا لم توجد أي درجات - طريقة
displayRecord()(const) تعرض السجل الكامل للطالب
لا تنسَ تنظيف الدرجات المخصّصة
dynamicallyفي المُدمّر، وincludeحواجز التضمين المناسبة لملف الترويسة.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().
يجمع هذا التحدي بين أعضاء البيانات الخاصة، وGetters العامة، وSetters المضبوطة مع التحقق، وفئة متداخلة: حيث تعمل جميعها معًا لإنشاء نظام سجلات طلابي جيد التغليف.
جرّب بنفسك
#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() لتحويل سلاسل الدرجات إلى doubles
// TODO: أنشئ كائن Student بالاسم والمعرف
// TODO: أضف الدرجات الثلاث جميعها إلى الطالب
// TODO: اعرض سجل الطالب الكامل
return 0;
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات الـ OOP
الملفات الخارجيةبناء وتجميع (Compilation) لغة C++ملفات الـ Header وملفات الـ Sourceالـ Namespaces والـ Scopeمقدمة في الـ OOP في C++الـ Classes مقابل الـ Objectsالمؤشر 'this'الـ Methods (الدوال الأعضاء)الـ Attributes (بيانات الأعضاء)أساسيات الـ Ctors والـ Dtorsمراجعة - آلة حاسبة بسيطة4خصائص الـ Class
أعضاء الـ Instance مقابل الـ Staticدوال الـ Getters والـ Settersدوال الأعضاء الثابتة (Const)الكلمة المفتاحية Mutableالدوال والمتغيرات الساكنة (Static)الدوال والفئات الصديقة (Friend)مراجعة - مدير الحساب البنكي7الوراثة
الوراثة الأساسيةمستويات الوصول في الوراثةترتيب استدعاء الـ Ctor والـ Dtorإعادة تعريف الدوال (Method Overriding)الدوال الافتراضية والـ VTableالوراثة المتعددةالوراثة الافتراضيةمراجعة - هيكلية الموظفين10نظرة عامة على STL
نظرة عامة وفلسفة STLحاويات STLالـ Iteratorsخوارزميات STLالـ Functors وتعبيرات Lambdaمراجعة - تكرار الكلمات13أنماط التصميم - الجزء الأول
مقدمة في أنماط التصميمنمط Singletonنمط Factory و Abstract Factoryنمط Builderنمط Observerنمط Strategy2إدارة الذاكرة
ذاكرة Stack مقابل Heapالمؤشرات والمراجعالذاكرة الديناميكية (new/delete)المؤشرات الذكية في C++RAII في C++مراجعة - مدير المصفوفات الديناميكية5التغليف (Encapsulation)
محددات الوصول في C++محددات الوصول بشكل متعمقإخفاء المعلوماتStruct مقابل Classالأصناف المتداخلة والداخليةمراجعة - نظام سجلات الطلاب8تعدد الأشكال (Polymorphism)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالتحميل الزائد للدوال (Function Overloading)مراجعة الدوال الافتراضية (Virtual Functions)الدوال الافتراضية البحتة (Pure Virtual Functions)الأصناف المجردة (Abstract Classes)تصميم الواجهات (Interface) في C++التحويل الديناميكي (Dynamic Casting) و RTTIملخص - حاسبة الأشكال11مفاهيم OOP المتقدمة
التركيب مقابل الوراثةالـ Mixins عبر CRTPنمط Pimplمحو النوع (Type Erasure)أصناف Enum والأنواع القويةمعالجة الاستثناءات في OOPتسلسلات الاستثناءات المخصصة14أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط قالب الطريقةنمط الحالةنمط التركيبRAII كنمط3المنشئات والموادم
المنشئ الافتراضيالمنشئ ذو المعاملاتمنشئ النسخمنشئ النقلقوائم تهيئة المنشئالمنشئات المفوضةتعمق في الموادمقاعدة الثلاثة / الخمسة / الصفرمراجعة - فئة String6تحميل العوامل (Operator Overloading)
مقدمة في تحميل العواملتحميل العوامل الحسابيةتحميل عوامل المقارنةعوامل Streamتحميل عامل التعيينتحميل العوامل [] و ()عوامل تحويل النوعمراجعة - Matrix Class9القوالب
قوالب الدوالقوالب الأصنافتخصيص القوالبالقوالب المتغيرةأساسيات SFINAE و Type Traitsمراجعة - الحاويات العامةتدرّب بنفسك: مترجم C++ عبر الإنترنت