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

dynamic_cast

التنزيل الآمن وقت التشغيل dynamic_cast

dynamic_cast يتحقّق فعليًا وقت التشغيل من نوع الكائن قبل التنزيل بتسلسل وراثي فيه تعدّد أشكال — يرجع nullptr أو يرمي استثناء عند الفشل بدل سلوك غير معرَّف.

على عكس static_cast، يستخدم dynamic_cast معلومات النوع وقت التشغيل (RTTI) للتأكّد أن الكائن المُشار إليه فعليًا من النوع المطلوب — لذا يتطلّب أن يملك الصنف الأساس دالة virtual واحدة على الأقل (عادة destructor افتراضي). مع المؤشّرات، فشل التحويل يُرجع nullptr بدل انهيار؛ مع المراجع، الفشل يرمي std::bad_cast لأنه لا يوجد مرجع فارغ يُرجعه بديلًا.

الصياغة

Derived* p = dynamic_cast<Derived*>(basePtr);
Derived& r = dynamic_cast<Derived&>(baseRef); // يرمي bad_cast عند الفشل

📄 مثال

class Shape { public: virtual ~Shape() = default; };
class Circle : public Shape { public: void draw() {} };

void render(Shape* s) {
    if (Circle* c = dynamic_cast<Circle*>(s)) {
        c->draw(); // نجح فقط لو s يشير فعليًا لـ Circle
    } else {
        // c هنا nullptr — فشل التحويل بأمان
    }
}

أهم النقاط

العنصرالوظيفة
تنزيل مؤشّريُرجع nullptr عند الفشل — يجب فحص النتيجة قبل الاستخدام
تنزيل مرجعيرمي std::bad_cast عند الفشل — يحتاج try/catch
يتطلّب virtualالصنف الأساس يحتاج دالة افتراضية واحدة على الأقل، وإلا خطأ ترجمة

💡 نصائح عملية

  • استخدمه فقط لما تحتاج فعليًا معرفة النوع الحقيقي وقت التشغيل — لو ممكن تصميم الكود بدون تنزيل أصلًا (عبر virtual functions)، هذا أفضل غالبًا
  • افحص دائمًا نتيجة تنزيل المؤشّر قبل استخدامها — النتيجة قد تكون nullptr بصمت

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

  • استخدامه على صنف أساس بلا أي دالة virtual — خطأ ترجمة لأن التحقّق يحتاج vtable
  • استخدام نتيجة تنزيل مؤشّر مباشرة دون فحص nullptr أولًا — انهيار فوري عند الفشل

خصائص ذات صلة

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