جاري التحميل...

الوراثة

في سي بلس بلس، الوراثة هي أحد المبادئ الأساسية للبرمجة الكائنية التوجه (OOP)، وتتيح للفئة المشتقة (Derived Class) أن ترث الخصائص والسلوكيات من الفئة الأساسية (Base Class). تكمن أهمية الوراثة في تمكين إعادة استخدام الكود، وتحسين تنظيمه، وتسهيل صيانته، بالإضافة إلى تمكين المطورين من إنشاء هيكليات برامج تعكس العلاقات الواقعية بين الكائنات، مثل أنواع المركبات أو الموظفين أو الأشكال الهندسية.
يتم استخدام الوراثة عندما تشترك فئات متعددة في خصائص أو سلوكيات متشابهة، أو عندما يكون مطلوباً استخدام تعدد الأشكال (Polymorphism) لكتابة خوارزميات مرنة وقابلة للتوسعة. في سي بلس بلس، يتم تعريف الوراثة باستخدام عامل النقطتين (:) مع محدد الوصول (public، protected، private) للتحكم في مستوى الوصول إلى أعضاء الفئة الأساسية. ترتبط الوراثة بمفاهيم سي بلس بلس الأساسية مثل الفئات، المنشئات، المُهلكات، الدوال الافتراضية، بالإضافة إلى الخوارزميات وهياكل البيانات.
في هذا الدرس، ستتعلم كيفية تعريف الفئات الأساسية والمشتقة، تطبيق ترتيب المنشئات والمُهلكات، استخدام الدوال الافتراضية لتحقيق تعدد الأشكال، وتطبيق نماذج الوراثة في مشاريع حقيقية. ستتمكن من فهم كيفية تبسيط الهياكل المعقدة، تعزيز وضوح الكود، ودعم التفكير الخوارزمي عند تصميم برامج سي بلس بلس احترافية.

مثال أساسي

text
TEXT Code
\#include <iostream>
\#include <string>

class Vehicle {
protected:
std::string brand;
int year;
public:
Vehicle(const std::string& b, int y) : brand(b), year(y) {}
virtual void displayInfo() const {
std::cout << "الماركة: " << brand << ", السنة: " << year << std::endl;
}
virtual \~Vehicle() {}
};

class Car : public Vehicle {
private:
int doors;
public:
Car(const std::string& b, int y, int d) : Vehicle(b, y), doors(d) {}
void displayInfo() const override {
std::cout << "الماركة: " << brand << ", السنة: " << year << ", عدد الأبواب: " << doors << std::endl;
}
};

int main() {
Vehicle v("مركبة عامة", 2020);
Car c("تويوتا", 2023, 4);

v.displayInfo();
c.displayInfo();

Vehicle* ptr = &c;
ptr->displayInfo(); // يعرض تعدد الأشكال

return 0;

}

يوضح المثال السابق أساسيات الوراثة في سي بلس بلس. فئة Vehicle هي الفئة الأساسية التي تحتوي على الخصائص العامة brand وyear، وتوفر دالة افتراضية displayInfo لتمكين التوسع في الفئات المشتقة. استخدام protected للأعضاء يسمح للفئة المشتقة بالوصول إليها دون الكشف عنها للعالم الخارجي، مما يحافظ على مبادئ التغليف.
فئة Car ترث بشكل public من Vehicle، وهو الأسلوب المفضل لعلاقة “is-a” في سي بلس بلس، حيث يضمن الحفاظ على واجهة الفئة الأساسية. تم استخدام قائمة التهيئة في منشئ Car لاستدعاء منشئ Vehicle، ما يضمن ترتيباً صحيحاً للبناء وإدارة الموارد. الدالة displayInfo تم إعادة تعريفها في Car باستخدام override لتوضيح تعدد الأشكال، حيث يمكن للدالة الافتراضية أن تستدعى عبر مؤشر إلى الفئة الأساسية وتنفذ الدالة المناسبة للفئة المشتقة في وقت التشغيل.
في الدالة main، تم إنشاء كائنات من Vehicle وCar، واستدعاء displayInfo لكل منها. عند استخدام مؤشر Vehicle* للإشارة إلى كائن Car، يوضح المثال كيف يمكن تحقيق تعدد الأشكال، وهي ميزة مهمة في تصميم أنظمة سي بلس بلس معقدة.

مثال عملي

text
TEXT Code
\#include <iostream>
\#include <vector>
\#include <memory>

class Employee {
protected:
std::string name;
double salary;
public:
Employee(const std::string& n, double s) : name(n), salary(s) {}
virtual void display() const {
std::cout << "الموظف: " << name << ", الراتب: " << salary << std::endl;
}
virtual double calculateBonus() const = 0; // دالة افتراضية صرفة
virtual \~Employee() {}
};

class Manager : public Employee {
private:
int teamSize;
public:
Manager(const std::string& n, double s, int t) : Employee(n, s), teamSize(t) {}
void display() const override {
std::cout << "المدير: " << name << ", الراتب: " << salary << ", حجم الفريق: " << teamSize << std::endl;
}
double calculateBonus() const override {
return salary * 0.1 + teamSize * 100;
}
};

class Developer : public Employee {
private:
std::string programmingLanguage;
public:
Developer(const std::string& n, double s, const std::string& lang) : Employee(n, s), programmingLanguage(lang) {}
void display() const override {
std::cout << "المطور: " << name << ", الراتب: " << salary << ", لغة البرمجة: " << programmingLanguage << std::endl;
}
double calculateBonus() const override {
return salary * 0.15;
}
};

int main() {
std::vector\<std::unique_ptr<Employee>> staff;
staff.push_back(std::make_unique<Manager>("أليس", 90000, 5));
staff.push_back(std::make_unique<Developer>("بوب", 80000, "سي بلس بلس"));

for (const auto& e : staff) {
e->display();
std::cout << "المكافأة: $" << e->calculateBonus() << std::endl;
}

return 0;

}

يعرض المثال العملي كيفية استخدام الوراثة في سيناريو حقيقي لإدارة الموظفين. فئة Employee هي فئة أساسية مجردة تحتوي على دالة صرفة calculateBonus، مما يضمن أن كل فئة مشتقة ستوفر طريقة حساب المكافأة الخاصة بها، وهو مثال على تعدد الأشكال وتوحيد الواجهة.
فئتا Manager وDeveloper ترثان بشكل public من Employee، وتعيدان تعريف display وcalculateBonus. Manager تضيف خاصية teamSize، بينما Developer تتتبع لغة البرمجة. استخدام الوراثة يقلل تكرار الكود، حيث يتم تعريف name وsalary مرة واحدة في الفئة الأساسية. استخدام std::unique_ptr يضمن إدارة ذاكرة آمنة وفق مبدأ RAII.
الدالة main تُظهر كيفية استخدام مؤشر متعدد الأنواع polymorphic pointer لتخزين فئات مختلفة في std::vector، واستدعاء الدوال الافتراضية بشكل ديناميكي، مما يزيد من مرونة وقابلية توسيع النظام، ويظهر تكامل الوراثة مع خوارزميات وهياكل بيانات سي بلس بلس.

أفضل الممارسات في الوراثة تشمل: استخدام المُهلكات الافتراضية في الفئات الأساسية لتجنب تسرب الذاكرة، استخدام public inheritance لعلاقات “is-a”، واستعمال قائمة التهيئة في المنشئات لتحسين الأداء. يجب تجنب قصّ الكائنات عند التعيين بالقيمة إلى فئة أساسية، واستخدام override عند إعادة تعريف الدوال الافتراضية لتجنب الأخطاء.
ينصح بعدم تعميق التسلسل الهرمي للفئات بشكل مفرط إذا كان يمكن استخدام التركيب بدلاً من الوراثة. للاستفادة من الأداء، استخدم خوارزميات وهياكل البيانات القياسية، وفحص جداول الدوال الافتراضية (vtable) عند الحاجة للتأكد من صحة التعددية الشكلية. اعتبارات الأمان تشمل منع الوصول غير المصرح به للأعضاء المحمية أو التسرب بسبب مؤشرات خاطئة.

📊 جدول مرجعي

سي بلس بلس Element/Concept Description Usage Example
الفئة الأساسية فئة يتم الوراثة منها class Vehicle { /* الأعضاء */ };
الفئة المشتقة فئة ترث من الفئة الأساسية class Car : public Vehicle { /* الأعضاء */ };
الدالة الافتراضية تتيح للفئة المشتقة إعادة تعريفها virtual void displayInfo() const;
الدالة الصرفة تفرض على الفئات المشتقة تنفيذها virtual double calculateBonus() const = 0;
التعددية الشكلية اختيار الدالة المناسبة في وقت التشغيل Vehicle* ptr = \&c; ptr->displayInfo();
قائمة تهيئة المنشئ تحسين بناء الكائنات المشتقة Car(const std::string& b,int y,int d): Vehicle(b,y),doors(d){}

خلاصة، الوراثة في سي بلس بلس توفر وسيلة منظمة لبناء العلاقات، إعادة استخدام الكود، وتحقيق التعددية الشكلية. اتقان هذه المفاهيم يمكن المطورين من إنشاء برامج قابلة للصيانة والتوسع، وتطبيق الخوارزميات على البيانات الهرمية بفعالية، ودمج مبادئ OOP بشكل سلس. من التوصيات متابعة دراسة الوراثة المتعددة، استخدام الفئات المجردة لتصميم الواجهات، واستكشاف أنماط التصميم التي تعتمد على الوراثة مثل Factory وStrategy. تجربة الوراثة في مشاريع حقيقية واستغلال مكتبة STL مع الكائنات متعددة الأشكال ستعزز من كفاءتك في سي بلس بلس.

🧠 اختبر معرفتك

جاهز للبدء

Test Your Knowledge

Test your understanding of this topic with practical questions.

4
الأسئلة
🎯
70%
للنجاح
♾️
الوقت
🔄
المحاولات

📝 التعليمات

  • اقرأ كل سؤال بعناية
  • اختر أفضل إجابة لكل سؤال
  • يمكنك إعادة الاختبار عدة مرات كما تريد
  • سيتم عرض تقدمك في الأعلى