Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

التحميل الزائد للدوال (Function Overloading)

جزء من قسم البرمجة كائنية التوجه في رحلة C++ على Coddy. الدرس 57 من 104.

تحميل الدوال الزائد يتيح لك تعريف عدة دوال بالاسم نفسه ولكن بقوائم معاملات مختلفة. يختار المصرّف الإصدار الصحيح استنادًا إلى الوسائط التي تمررها. وهذا شكل أساسي من تعدد الأشكال في وقت الترجمة.

لكي تعمل عملية overloading، يجب أن تختلف الدوال في signature الخاصة بها - عدد المعاملات، أو أنواعها، أو كلاهما:

class Calculator {
public:
    int add(int a, int b) {
        return a + b;
    }
    
    double add(double a, double b) {
        return a + b;
    }
    
    int add(int a, int b, int c) {
        return a + b + c;
    }
};

Calculator calc;
calc.add(5, 3);        // يستدعي add(int, int)
calc.add(2.5, 3.7);    // يستدعي add(double, double)
calc.add(1, 2, 3);     // يستدعي add(int, int, int)

يفحص المترجم كل استدعاء ويطابقه مع overload المناسبة. يحدث هذا بالكامل في وقت الترجمة، لذلك لا توجد تكلفة إضافية في وقت التشغيل.

مهم: نوع الإرجاع وحده لا يميّز بين الدوال المحمّلة بشكل زائد. سيؤدي ما يلي إلى حدوث خطأ في المصرّف:

int getValue();
double getValue();  // خطأ: لا يمكن التحميل الزائد حسب نوع الإرجاع فقط

يجعل تعدد التحميل للدوال شفرتك أكثر وضوحًا. بدلًا من إنشاء أسماء منفصلة مثل addInts وaddDoubles وaddThreeInts، تستخدم اسمًا واحدًا ذا معنى وتدع المترجم يتولى الباقي.

challenge icon

التحدي

سهل

لنبنِ فئة لتنسيق الرسائل توضّح قوة function overload. ستنشئ فئة Formatter تحتوي على عدة أساليب format() تتعامل مع أنواع مختلفة من inputs، مما يتيح للمصرّف اختيار الإصدار الصحيح استنادًا إلى ما تمرّره إليه.

ستنظّم الشيفرة في ملفين:

  • Formatter.h: Define فئة Formatter تحتوي على أساليب format() ذات overload للتعامل مع سيناريوهات مختلفة:
    • method يأخذ std::string single ويطبع: Message: <text>
    • method يأخذ std::string وint priority، ويطبع: [Priority <priority>] <text>
    • method يأخذ std::string وdouble timestamp، ويطبع: [<timestamp>s] <text>
    • method يأخذ three parameters من النوع std::string (sender وreceiver وmessage) ويطبع: From <sender> to <receiver>: <message>
    يجب أن تحمل جميع الأساليب الاسم format(): سيختار المصرّف الأسلوب الصحيح استنادًا إلى الوسائط.
  • main.cpp: اقرأ four inputs (كل واحد في سطر منفصل):
    1. نص message بسيط
    2. مستوى priority (عدد صحيح)
    3. قيمة timestamp (double)
    4. اسم sender

    أنشئ Formatter object وأظهر عمل الأساليب الأربعة ذات overload:

    • Call على format() باستخدام نص message فقط
    • Call على format() باستخدام نص message وpriority
    • Call على format() باستخدام نص message وtimestamp
    • Call على format() باستخدام sender، مع استخدام "Admin" بوصفه receiver، ونص message

على سبيل المثال، مع inputs هي System ready و3 و12.5 وServer:

Message: System ready
[Priority 3] System ready
[12.5s] System ready
From Server to Admin: System ready

لاحظ أنك تستدعي اسم method نفسه format() أربع مرات، لكن كل استدعاء يشغّل إصدارًا مختلفًا استنادًا إلى أنواع الوسائط وعددها. هذا هو polymorphism وقت الترجمة عمليًا: يحدّد المصرّف أي overload سيستخدم قبل أن يبدأ البرنامج بالعمل.

جرّب بنفسك

#include <iostream>
#include <string>
#include "Formatter.h"

using namespace std;

int main() {
    // اقرأ المدخلات
    string message;
    getline(cin, message);
    
    int priority;
    cin >> priority;
    
    double timestamp;
    cin >> timestamp;
    cin.ignore();
    
    string sender;
    getline(cin, sender);
    
    // TODO: أنشئ كائن Formatter
    
    // TODO: استدعِ format() مع نص الرسالة فقط
    
    // TODO: استدعِ format() مع نص الرسالة وpriority
    
    // TODO: استدعِ format() مع نص الرسالة وtimestamp
    
    // TODO: استدعِ format() مع sender، و"Admin" كمستلم، ونص الرسالة
    
    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C++ عبر الإنترنت