יום רביעי

Operator Overloading


המשמעות של Operator Overloading: אפשרות לתת לאופרטור של C++ משמעות נוספת. העיקרון דומה לזה של function overloading שם פונקציה עם אותו שם יכולה להתקיים במספר צורות ולבצע פעולות שונות. ניתן לעשות overloading רק על אופרטורים חוקיים של C++. כך ש-$ למשל לא כלול אבל +,->,= וגם ! [] ()  % & ועוד ניתנים ל-overloading.
למה צריך את זה? דוגמא: Operator Overloading על האופרטור +.
האופרטור + יכול לחבר שני סקלארים, למשל c=a+b. אבל נניח ש-a ו-b הם אובייקטים מסוג Example. מה יקרה אם נרצה לחבר אותם?
הנה דוגמא:

  1. /*
  2.  * oveloading.cpp
  3.  *
  4.  *  Created on: Mar 21, 2012
  5.  *      Author: ronen halevy
  6.  */

  7. #include <iostream>
  8. using namespace std;

  9. class Example{
  10. private:
  11. int a;
  12. int b;
  13. int c;
  14. public:
  15. Example(int a, int b):a(a),b(b){c = a + b;}
  16. void sum(){c = a+b;}
  17. }
  18. int main(){
  19. Example ex1(1,2);
  20. Example ex2(2,3);
  21. Example ex3 = ex1+ex2
  22. }


בשורה 24 מופעל האופרטור + על שני האובייקטים ex1 ו-ex2.
תוצאת הקומפילציה - שגיאה:
error: no match for ‘operator+’ in ‘ex1 + ex2’

לא ניתן היה לצפות לתוצאה אחרת, שכן ה + לא יודע לחבר את האובייקטים האלה.
ה- operator overloading  מאפשר להגדיר פעולת + חדשה שתתאים לאובייקטים מסוג Example.
את פעולת ה + החדשה נוכל להגדיר כרצוננו. במקרה הנ"ל בחרתי לבצע חיבור של כל ה-data members של ה-class כך שהתוצאה תהיה:

ex3.a = 8
ex3.b = 5
ex3.c = 8
אני מניח שהחישוב ברור אבל אפרט בכ"ז: 

ex3.a = ex1.a + ex2.a = 1 + 2 = 3
ex3.b = ex1.b + ex2.b = 2 + 3 = 5
ex3.c = ex1.c + ex2.c = (1+2) + (2+3) =8

 זו התוצאה שנקבל אחרי שה-operator overloading יוגדר לפי הדרישות הנ"ל.
אז איך מגדירים operator overloading?
כל שצריך לבצע הוא להגדיר את הפונקציה של האופרטור לפי התבנית הבאה:
type operator op(parameter list);
ובדוגמא שלנו למשל:
Example operator+(Example b);
למה המתודה מקבלת פרמטר יחיד - Example b ולא מקבלת את שני המחוברים? כלומר, למה לא לכתוב זאת כך:
Example operator+(Example a, Example b);
תשובה: 
רק המחובר השני מועבר כפרמטר. המחובר הראשון הוא האוביקט הלוקאלי (this).

הכל יהיה ממש ברור כשנסתכל על הדוגמא כולה. הנה היא:


  1. /*
  2.  * oveloading.cpp
  3.  *
  4.  *  Created on: Mar 21, 2012
  5.  *      Author: ronen halevy
  6.  */

  7. #include <iostream>
  8. using namespace std;

  9. class Example{
  10. private:
  11. int a;
  12. int b;
  13. int c;
  14. public:
  15. Example(int a, int b):a(a),b(b){c = a + b;}
  16. Example(){}

  17. void sum(){c = a+b;}
  18. int get_a(){ return a;}
  19. int get_b(){ return b;}
  20. int get_c(){ return c;}
  21. void set_a(int _a){ a = _a;}
  22. void set_b(int _b){ b = _b;}
  23. void set_c(int _c){ c = _c;}
  24. Example operator+(Example b);
  25. };
  26. Example Example::operator +(Example ex){
  27. Example sum;
  28. sum.set_a(a + ex.get_a());
  29. sum.set_b(b + ex.get_b());
  30. sum.set_c(c + ex.get_c());
  31. return(sum);
  32. }

  33. int main(){
  34.     Example ex1(1,2);
  35.     Example ex2(2,3);
  36.     Example ex3;
  37.     ex3 = ex1.operator+(ex2); 
  38.     ex3 = ex1+ex2;
  39.     cout << " " << ex3.get_a() << " " << ex3.get_b() <<" " << ex3.get_c();
  40. }

שורות 13-15 - בכתום: ה-data members של ה-class. הם יהיו האלמנטים שיחוברו באופרטור + שנגדיר.
שימו לב: ה-data members הנ"ל הם מסוג private. כדי שנוכל לגשת אליהם מבחוץ מוגדרים Setters ו- Getters עבור a, b ו-c.
שורות 21-26 - בצהוב: ה-Getters וה-Setters.
שורה 27 - בירוק ליים:
Example operator+(Example b);
זו ההגדרה של ה-operator overloading function. תבנית הפונקציה היא זו:
type operator op(parameter list);
כשבמקרה הנל:
ה-type הוא Example
ה- op הוא +
והפרמטר הוא המחובר השני Example b.

שורות 29-35: ממוש ה- operator overloading function. כפי שצוין למעלה, הגישה ל-data members של האובייקטים sum ו-ex אינה אפשרית כי הם private. מסיבה זו, השתמשנו ב-Setters ו- Getters שהם public.
 ונעבור לפונקציה המפעילה - main.
שורות 41 ו-42 מדגימות הצגה שונה של פונקצית האופרטור, אך הן שתיהן אקוויולנטיות.
שורה 41 מציגה פורמט ארוך יותר, שתואם את הפורמט הקונבנציונלי. המתודה +operator של האובייקט ex1 מופעלת עם פרמטר ex2.

   ex3 = ex1.operator+(ex2); 
והנה ההצגה המקוצרת, אליה שאפנו להגיע. פשוט משמיטים את operator.

    ex3 = ex1 + ex2;


הפלט למסך - בדיוק כפי שצפינו:

 3 5 8


אין תגובות:

הוסף רשומת תגובה