تتجاوز الوظيفة والحمل الزائد في C ++ و Delphi
SPACESOFT 【الرمال الليلية المظلمة】
في البرمجة الموجهة للكائنات ، عندما تستمر الفئة الفرعية في الوظائف من الفئة الأساسية ، قد تحتاج الفئة الفرعية إلى التعامل مع بعض الوظائف بشكل مختلف عن الفئة الأساسية ، مثل:
فئة chuman
{
عام:
void saymyname () // اطبع اسم الكائن
{
cout << مرحبًا ، أنا إنسان << endl ؛
}
} ؛
ثم من الواضح ، إذا كان للفئة الفرعية وظيفة saymyname مع نفس الاسم ، نفس المعلمة وقيمة الإرجاع (جملة واحدة ، نفس الوظيفة) ، ما هي الوظيفة التي ستتصل بها؟ على سبيل المثال ، هناك Class Class الآن
Class Clark: chuman العامة
{
عام:
باطل saymyname ()
{
cout << مرحبًا ، أنا مارك << endl ؛
}
} ؛
ثم علينا أن نسأل ، قطاع البرنامج التالي:
chuman *ph = new cmark ؛
إذا (PH)
ph-> saymyname () ؛
آخر
كوت << خطأ!
حذف درجة الحموضة ؛
الرقم الهيدروجيني = فارغ ؛
هل مرحبا ، أنا علامة نريد طباعتها؟
لا. إنه يخرج مرحبًا ، أنا إنسان. إنه لأمر مروع ، وعندما نشير إلى شخص ونطلب منه أن يقول اسمه ، يخبرنا أنه "شخص" بدلاً من قول اسمه. والسبب في هذه المشكلة هو أن الإشارة إلى الفئة المشتقة العامة مع مؤشر الطبقة الأساسية ، يمكنك الوصول إلى وظائف الأعضاء للفئة المشتقة التي تستمر من الفئة الأساسية. ولكن إذا كانت هناك وظائف تحمل نفس الاسم في الفئة المشتقة ، فلا تزال النتيجة تصل إلى وظيفة الاسم نفسه للفئة الأساسية ، بدلاً من وظيفة الفئة المشتقة نفسها. في الواقع ، ما نريده هو تحديد أي من هذه الوظائف التي تحمل نفس الاسم يجب أن يطلق عليها النوع الحقيقي للكائن ، أي أن هذا الدقة ديناميكية. أو يمكننا القول أنه عندما يكون الكائن نوعًا فرعيًا ، فإن تنفيذه بنفس الاسم في الفئة الفرعية يتجاوز تنفيذ الفئة الأساسية.
لنبدأ بمعالجة C ++ لهذه المشكلة.
هذا مثال نموذجي على تعدد الأشكال في C ++. لكي تكون محددًا ، هو استخدام الكلمات الرئيسية الافتراضية لوصف الوظيفة كدالة افتراضية.
فئة chuman
{
عام:
void void saymyname () // اطبع اسم الكائن
{
cout << مرحبًا ، أنا إنسان << endl ؛
}
} ؛
وبهذه الطريقة ، لا تزال الرموز الأخرى كما هي ، لكن CMMARK تعرف بالفعل كيف تقول اسمها. لا يهم ما إذا كانت وظيفة saymyname () لـ CMMARM قد أضافت كلمة مفتاح افتراضي ، لأنه وفقًا لأحكام بناء جملة C ++ ، لأنها تتجاوز وظيفة chuman التي تحمل نفس الاسم ، تصبح افتراضية نفسها. أما لماذا يكون للكلمة الرئيسية الافتراضية مثل هذا التأثير السحري؟ يشرح C ++ faq lite هذا على النحو التالي: في C ++ ، "يتم تحديد وظائف الأعضاء الافتراضية ديناميكيًا (في وقت التشغيل). أي أن وظائف الأعضاء (في وقت التشغيل) يتم تحديدها ديناميكيًا ، ويعتمد التحديد على نوع الكائن. ، وليس نوع المؤشر/الإشارة إلى هذا الكائن ". لذلك يجد الرقم الهيدروجيني الخاص بنا أنه يشير فعليًا إلى كائن من النوع Cmark ، وليس Chuman المعلن بنوعه الخاص ، لذلك يدعو Saymyname من Cymark بذكاء.
يستخدم Delphi تجاوز الكلمات الرئيسية لتوضيح تجاوزات الوظائف. يجب أن تكون الوظيفة المكتوبة فوقها افتراضية أو ديناميكية ، أي أن الوظيفة يجب أن تحتوي على أحد هذين المؤشرين عند إعلانه ، مثل:
رسم الإجراء
عندما تحتاج إلى تجاوز ، تحتاج فقط إلى إعادة صياغة مؤشر التجاوز في الفئة الفرعية.
رسم الإجراءات ؛
من الناحية النحوية ، فإن التصريحات بأنها افتراضية وديناميكية مكافئة. الفرق هو أن الأول يعمل على تحسين السرعة في التنفيذ ، بينما يحسن الأخير حجم الرمز.
ماذا لو أن كل من الفئة الأساسية والفئة الفرعية تحتوي على نفس اسم الوظيفة والمعلمة ، ولم تتم إضافة مؤشر التجاوز إلى الفئة الفرعية؟ هذا هو أيضا صحيح النحاها. هذا يعني أن تنفيذ وظيفة وظيفة الفئة الفرعية يخفي تطبيق الفئة الأساسية ، على الرغم من وجود كلاهما في الفئة المشتقة. ثم دعنا نعود إلى الموقف الموضح في المثال الأول في بداية هذا المقال: عندما نشير إلى شخص ما ونطلب منه أن يقول اسمه ، يخبرنا أنه "شخص" ، بدلاً من قوله اسم.
تجدر الإشارة إلى أنه على عكس وظيفة التحميل الزائد ووظيفة التحميل الزائد التي نسميها في كثير من الأحيان الزائد في C ++ ، في Delphi ، فإن التحميل الزائد هو ما نسميه عادةً التحميل الزائد. بالطبع ، عندما يكون الحمل الزائد للوظيفة هو نفسه معلمات الوظيفة للفئة الأساسية ، يكون تنفيذ الفئة الأساسية مخفية ، تمامًا مثل المعلمات المذكورة أعلاه. التجاوز يعني جعل الوظيفة المكتوبة غير مرئية وفي الكتابة فوقها بالفعل ، وسيختفي التنفيذ الأصلي. لهذا السبب ، فإن العديد من المقالات وحتى بعض الكتب قد ترجمت عن طريق الخطأ إلى التحميل الزائد ، والتي أعتقد أنها غير مناسبة.