الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

ما هو سبب الحاجه الى Operator Overloading

بدأه صمودا في 24 سبتمبر 2012 · 6 رد · 1,631 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم,

ما هو سبب الحاجه الى Operator Overloading؟

اجد صعوبه كبيره في فهمها, عندما نحاول ان نعمل cout << ObejtName; نحصل على خطأ و لا بد استخدام ال operator

ممكن توضيح لهذا الامر؟ و هل سي بلس بلس في مراحله المتقدمه تشبه اكواد الاوبريتور؟ لاني اراها كشيء غريب في syntax

#2

إعادة تعريف المعاملات مفيدة إذا إستُخدمت بشكل صحيح وفي مكانها. أفضل تطبيق لها برأيي هي string :

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char **argv)
{
    string right = "ABC";
    string left  = "123";

    cout << right[0] << endl;
    cout << right + left << endl;
    right += "DEF";
    cout << right << endl;

    return 0;
}

string عبارة عن "class" تقوم بإعادة تعريف العديد من المعاملات كي تُبدو كنوع أصلي في اللغة.

1
#3

شكرا لك

ال string class is easy

لكن رأيت استخدام ال stream operator للعمل مع classes and objects

طريقه كتابته لتساعد على عمليه تعريف الاوبجكت عند استخدام cout and cin

اربكتني كثيرا

#4
صمودا كتب:

شكرا لك

ال string class is easy

لكن رأيت استخدام ال stream operator للعمل مع classes and objects

طريقه كتابته لتساعد على عمليه تعريف الاوبجكت عند استخدام cout and cin

اربكتني كثيرا

لعلي وجدت الجواب و ربما اكون مخطأ

Compiler لا يمكنه تمييز class defined data types حتى يمكننا ان نستخدم

Object1 == Object2

هذه ليست Built in data types as integers for example

لذا يتوجب علينا ان نقوم بكتابه داله تقوم بهذه الامر و استخدامها خارج الكلاس مثلا في الداله مين الرئيسيه

لذا قمت بعمل هذا المثال البسيط بعد التدرب عليه من مصدر خارجي

#include <iostream>
using namespace std;

class date

{

private:
    int day, month, year;

public:
  date(int d, int m, int y)
    {
        day = d;
        month = m;
        year = y;
    }
    // Default constructor
    date()
    {
        day = 0;
        month = 0;
        year = 0;

    }

    void setDate(int d, int m, int y)

    {
        month = m;
        day = d;
        year = y;
    }

    int getDate()
    {
        cout << day << ":" << month << ":" << year << endl;
        return 0;
    }

    void setDay(int d)

    {

        day = d;
    }

    void setMonth(int m)

    {
        if (m < 1 || m > 12)
            cout << "Invalid month value! " << endl;
        else
        month = m;
    }

    void setYear(int y)

    {

        year = y;
    }

    int getDay()

    {

        return day;
    }

    int getMonth()

    {

        return month;
    }

    int getYear()

    {

        return year;
    }

    void addDay(int d)

    {

        day += d;
    }

    bool equal(date dt)
    {

        if ((month == dt.month) && (day == dt.day) && (year == dt.year))
            return true;
        else
            return false;
    }
};

int main()

{
    date today(24,9,2012);
    today.getDate();
    today.addDay(6);
    today.getDate();
    date tomorrow = today;
    tomorrow.getDate();
    tomorrow.setDay(18);
    if (tomorrow.equal(today))
        cout << "Same day!" << endl;
    else
        cout << "different day" << endl;

}
#5

فى الجافا كل الفئات ترث الفئة Object التى تحتوى الدالة toString وهذه الدالة هى التى يتم استدعائها عن استخدام الكائن مع stream output

مثلا

System.out.println(myObject);

طبعا يمكنك اعادة كتابة هذه الدالة فى الفئة الخاصة بك حتى تتحكم فى الجملة التى يتم طباعتها

اما السى بلس بلس لا تتبع نفس الأسلوب وانما تستخدم Operator Overloading

ارى انه افضل من أسلوب الجافا فلست مضطرا للوراثة من كائن فى كل الفئات التى تنشأها

علاوة على انه يقدم لك مميزات كثيرة مثل الجمع والطرح والمقارنة

1


﴿وَمَا كَانَ اللَّهُ لِيُعَذِّبَهُمْ وَأَنْتَ فِيهِمْ ۚ وَمَا كَانَ اللَّهُ مُعَذِّبَهُمْ وَهُمْ يَسْتَغْفِرُونَ﴾

الأنفال ۳۳                                  
 

#6
MOHAMED FATHEI كتب:

فى الجافا كل الفئات ترث الفئة Object التى تحتوى الدالة toString وهذه الدالة هى التى يتم استدعائها عن استخدام الكائن مع stream output

مثلا

System.out.println(myObject);

طبعا يمكنك اعادة كتابة هذه الدالة فى الفئة الخاصة بك حتى تتحكم فى الجملة التى يتم طباعتها

اما السى بلس بلس لا تتبع نفس الأسلوب وانما تستخدم Operator Overloading

ارى انه افضل من أسلوب الجافا فلست مضطرا للوراثة من كائن فى كل الفئات التى تنشأها

علاوة على انه يقدم لك مميزات كثيرة مثل الجمع والطرح والمقارنة

شكرا لك اخي لقد قمت بالتعديل على الكود ادناه باستخدام Operator overloading

#include <iostream>
using namespace std;

class date

{

private:
    int day, month, year;

public:
  date(int d, int m, int y)
    {
        day = d;
        month = m;
        year = y;
    }
    // Default constructor
    date()
    {
        day = 0;
        month = 0;
        year = 0;

    }

    void setDate(int d, int m, int y)

    {
        month = m;
        day = d;
        year = y;
    }

    int getDate()
    {
        cout << day << ":" << month << ":" << year << endl;
        return 0;
    }

    void setDay(int d)

    {

        day = d;
    }

    void setMonth(int m)

    {
        if (m < 1 || m > 12)
            cout << "Invalid month value! " << endl;
        else
        month = m;
    }

    void setYear(int y)

    {

        year = y;
    }

    int getDay()

    {

        return day;
    }

    int getMonth()

    {

        return month;
    }

    int getYear()

    {

        return year;
    }

    void addDay(int d)

    {

        day += d;
    }

    bool equal(date dt)
    {

        if ((month == dt.month) && (day == dt.day) && (year == dt.year))
            return true;
        else
            return false;
    }
};


    bool operator==(date object1, date object2)
{
        return ((object1.getDay() == object2.getDay())
                && (object1.getMonth() == object2.getMonth())
                && (object1.getYear() == object2.getYear()));

}
int main()

{
    date today(11,11,2011);
    date tomorrow = today;
    tomorrow.setYear(2012);
    if (tomorrow == today)
        cout << "Same day!" << endl;
    else
        cout << "It's a different day! " << endl;

}
#7

السلام عليكم

لتعريف معامل موجود مسبقا اسمه op, نقوم بإعادة تعريف الدالة operator op بإحدى الطريقتين :

  1. إما أن نجعلها دالة مستقلة (عادة ما تكون صديقة)
  2. أو أن تكون دالة عضوة.

في الحالة الأولى, إذا كان op عبارة عن معامل أحادي فالعبارة a op b تُكافئ :

operator op (a, b)

أما في الحالة الثانية فالعبارة تُكافئ :

a.operator op (b)

ملاحظة : تحتفظ المعاملات التي تمت إعادة تعريفها بأولويتها عند التنفيذ.

هناك حالات خاصة في إعادة تعريف المعاملات, تبرز هذه الخصوصية عن التعامل مع إحدى المعاملات التالية :

[], (), ->, new and delete

المعاملات السابقة يجب إعادة تعريفها كدالة عضوة و ليست كصديقة.

معامل الإسناد و معامل المرجع يملكان تعريفا مُسبقا بحيث يمكن استخدامهما مع أي نوع من الكائنات. لكن هذا لا يمنع من إعادة تعريفهما ان اقتضت الضرورة.

أما إعادة تعريف المعامل new في فئة معينة, فتتم باستخدام الدالة ذات التوقيع :

void * new (size_t)

تستقبل هذه الدالة وسيطا واحدا وهو حجم الكائن المراد حجزه, و تعيد عنوان المساحة التي تم حجزها.

أما delete فالدالة المرافقة لها, توقيعها كالتالي :

void delete (type *)

تستقبل وسيطا واحدا وهو عنوان المساحة المراد تحريرها.

عند إعادة تعريف المعاملين new و delete يمكننا استدعاء new و delete الأصليين باستخدام معامل تحديد المدى ( :: ).

الجزء الثالث من سلسلة اختبر قدراتك يحتوي على مثال جيد في إعادة تعريف المعاملات, يمكنك الإستفادة منه.

1

مواضيع مشابهة