C++منع إمكانية إعادة تعريف الدوال
- الكلمة
final
- أمثلة شاملة على الكلمة
final
الكلمة final
إذا كنت تريد منع الكلاس الإبن من إعادة تعريف الدالة التي ورثها من الكلاس فيمكنك جعل نوع الدالة virtual final
حتى أنه يمكنك جعل نوع الكلاس بأكمله final
لا يمكن إعادة تعريف أي دالة موجودة فيه بهدف أن يتم استخدام الدوال الموجودة فيه كما هي.
ملاحظة: تم إضافة هذه الكلمة إبتداءاً من الإصدار C++ 11 و الإصدارات اللاحقة.
مصطلحات تقنية
- الدالة التي لا يمكن إعادة تعريفها يقال لها في العادة دالة ثابتة.
- الكلاس الذي لا يمكن إعادة تعريف أي شيء موجود فيه يقال له كلاس ثابت.
الكلاس الثابت لا يسمح لك بالوراثة منه لأن الوراثة بالأساس فكرتها أنك ترث الشيء بهدف تطويره أو الزيادة عليه.
بمعنى آخر يمكنك إنشاء كائنات منه فقط و استخدام ما هو موجود فيه.
الكلمة final
يمكن استخدامها كإسم لمتغير, دالة, مصفوفة, كائن إلخ.. لأنها لا تعتبر من الكلمات المحجوزة ( Keywords ) في اللغة.
أمثلة شاملة على الكلمة final
في المثال التالي قمنا بتعريف كلاس إسمه Base
يحتوي على دالة ثابتة إسمها func()
.
بعدها قمنا بتعريف كلاس إسمه Derived
يرث من الكلاس Base
و حاولنا فيه إعادة تعريف الدالة func()
لتنبيهك من الخطأ الذي قد يظهر في حال حاولت إعادة تعريف دالة ثابتة في الكلاس الذي يرثها.
المثال الأول
using namespace std; // func يحتوي على دالة ثابتة إسمها Base هنا قمنا بتعريف كلاس إسمه class Base { public: virtual void func() final { cout << "Base class default behaviour \n"; } }; // func و فيه قمنا بإعادة تعريف الدالة الثابتة Base يرث من الكلاس Derived هنا قمنا بتعريف محتوى الكلاس class Derived : public Base { public: void func() override // هذا السطر الذي سيسبب المشكلة عند التشغيل { cout << "Derived class overridden behaviour \n"; } }; // main() هنا قمنا بتعريف الدالة int main() { return 0; }
سيظهر الخطأ التالي عند التشغيل.
note: overridden function is 'virtual void Base::func()'
In member function 'virtual void Derived::func()'
في المثال السابق حدث الخطأ فعلياً بسبب السطر 19 حيث أن المترجم قال بأنه لا يمكن إعادة تعريف الدالة func()
في الكلاس Derived
الذي ورثها لأنها في الكلاس الأب Base
معرّفة كدالة ثابتة.
في المثال التالي قمنا بتعريف كلاس ثابت إسمه Base
يحتوي على دالة إسمها func()
.
بعدها قمنا بتعريف كلاس إسمه Derived
يرث من الكلاس Base
فقط لتنبيهك من الخطأ الذي قد يظهر في حال حاولت الوراثة من كلاس ثابت.
المثال الثاني
using namespace std; // func يحتوي على دالة إسمها Base هنا قمنا بتعريف كلاس ثابت إسمه class Base final { public: void func() { cout << "Base class default behaviour \n"; } }; // و طبعاً هذا الأمر سيسبب مشكلة عند التشغيل Base يرث من الكلاس Derived هنا قمنا بتعريف محتوى الكلاس class Derived : public Base { }; // main() هنا قمنا بتعريف الدالة int main() { return 0; }
سيظهر الخطأ التالي عند التشغيل.
في المثال السابق حدث الخطأ فعلياً بسبب السطر 16 حيث أن المترجم قال بأنه لا يمكن الوراثة من الكلاس Base
لأنه كلاس ثابت.
في المثال التالي قمنا بتعريف كلاس ثابت إسمه Base
يحتوي على دالة إسمها func()
.
بعدها قمنا بإنشاء كائن منه و استدعاء الدالة الموجودة فيه.
المثال الثالث
using namespace std; // func يحتوي على دالة إسمها Base هنا قمنا بتعريف كلاس ثابت إسمه class Base final { public: void func() { cout << "Base class default behaviour \n"; } }; // main() هنا قمنا بتعريف الدالة int main() { // b إسمه Base هنا قمنا بإنشاء كائن من الكلاس Base b; // b من الكائن func() هنا قمنا باستدعاء الدالة b.func(); return 0; }
سنحصل على النتيجة التالية عند التشغيل.
Base class default behaviour