تخطَّ إلى المحتوى

virtual

الدوال الافتراضية virtual

virtual تجعل استدعاء الدالة يُحدَّد وقت التشغيل حسب النوع الفعلي للكائن، لا حسب نوع المؤشّر أو المرجع المُعلَن — أساس تعدّد الأشكال.

بدون virtual، لو كان عندك مؤشّر من نوع الصنف الأساس يشير لكائن من صنف مشتق، فاستدعاء دالة عبره يُنفّذ نسخة الصنف الأساس دائمًا — حتى لو الكائن الحقيقي من نوع مختلف. virtual تحل هذا عبر جدول دوال افتراضي (vtable) يبحث عن النسخة الصحيحة وقت التشغيل حسب نوع الكائن الفعلي، وهذا جوهر تعدّد الأشكال (polymorphism).

إذا كان صنفك سيُشتق منه، اجعل الهادم (destructor) virtual أيضًا — وإلا فحذف كائن مشتق عبر مؤشّر للصنف الأساس لن يستدعي هادم الصنف المشتق، ما يسبب تسريب موارد.

الصياغة

class Base {
public:
    virtual ReturnType method();
    virtual ~Base(); // هادم افتراضي مهم
};

📄 مثال

class Shape {
public:
    virtual double area() const { return 0; }
    virtual ~Shape() = default;
};

class Circle : public Shape {
    double r;
public:
    Circle(double r) : r(r) {}
    double area() const override { return 3.14159 * r * r; }
};

Shape* s = new Circle(5);
std::cout << s->area(); // ينادي نسخة Circle، مو Shape
delete s;

أهم النقاط

العنصرالوظيفة
virtual method()دالة يُحدَّد أي نسخة منها تُستدعى وقت التشغيل حسب نوع الكائن الفعلي
virtual ~Class()هادم افتراضي — ضروري بأي صنف أساس يُشتق منه
pure virtual = 0دالة بلا تنفيذ بالصنف الأساس تجعله صنفًا مجرّدًا (abstract)

💡 نصائح عملية

  • أي صنف يُتوقّع أن يُشتق منه ويُستخدم عبر مؤشّرات للصنف الأساس، اجعل هادمه virtual دائمًا
  • virtual تكلّف أداءً بسيطًا (بحث بجدول vtable) — لا تستخدمها إلا فعليًا بحاجة لتعدّد الأشكال

⚠️ أخطاء شائعة

  • نسيان virtual على الهادم بصنف أساس يُشتق منه — يسبب تسريب موارد عند الحذف عبر مؤشّر الصنف الأساس
  • توقّع أن الدالة تتصرف تعدّديًا بدون كتابة virtual أصلًا — بدونها يُحدَّد الاستدعاء حسب النوع المُعلَن لا الفعلي

خصائص ذات صلة

🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار CPP الكامل بالعربي.