מה משמעות המילה this? this מייצגת מצביע לאובייקט אליו המתודה שייכת.
נראה דוגמא בה נדגים את השימוש ב-this.
הדוגמא מראה שני שימושים בהם this מועילה:
1. במצב בו שם פרמטר לפונקציה זהה לשם משתנה של הפונקציה. במקרה זה הפרמטר "מכסה" את המשתנה. נפתור את הבעיה תוך שימוש ב-this (ראו למטה - שורת הקוד בכתום).
2. מצב בו דרוש pointer לאובייקט הלוקלי. נראה מתודה שצריכה להחזיר pointer כזה. (מודגש בצהוב).
הנה הדוגמא ואחריה הסבר.
הנה הדוגמא ואחריה הסבר.
- /*
- * this.cpp
- *
- * Created on: Mar 20, 2012
- * Author: ronen halevy
- */
- #include <iostream>
- using namespace std;
- class Example{
- public:
- int a;
- int b;
- Example(int a, int b);
- Example *check_bigger_a(Example &ex);
- };
- Example::Example(int a, int b){this->a = a; Example::b =b;}
- Example *Example::check_bigger_a(Example &ex){
- if(a > ex.a)
- return this;
- else
- return &ex;
- }
- int main(){
- Example ex1(1,2);
- Example ex2(3,4);
- Example *ex3;
- ex3 = ex1.check_bigger_a(ex2);
- cout << ex3->a;
- }
הסבר:
נתיל עם בעית כסוי המשתנה ע"י פרמטר:
שורה 20: זה ה-constructor.
מה היה קורה אם הוא היה נראה כך:
Example::Example(int a, int b){a = a; b =b;}
תשובה: ב- C++ זהו באג. a ו-b לא יקבלו את ערכי הפרמטרים. הסיבה: בגלל השמות הזהים, הקומפיילר לא מבחין בין ה- class member לבין הפרמטר שהוא automatic variable.
ישנם מספר פתרונות לבעיה:
1. לדאוג שלפרמטרים יהיה שם אחר, למשל:
Example::Example(int _a, int _b){a = _a; b = _b;}
2. להשתמש בשם ה-class שיזהה את ה-class members באופן הבא:
Example::Example(int a, int b){Example:a = a; Example:b = b;}
3. להשתמש ב-this:
Example::Example(int a, int b){this->a = a; this->:b = b;}
קיים גם פתרון נוסף - שימוש ב-initialization list. זה מתאים רק ל-constructors, אבל במקרה הדוגמא הנ"ל היא של contructor:
Example::Example(int a, int b): a(a), b(b){}
לכל המעונין - הנה קישור לפוסט על initialization list.
שורה 20 מדגימה שימוש בפתרונות 2 ו-3. הנה היא מועתקת שוב:
Example::Example(int a, int b){this->a = a; Example::b =b;}
שימוש נוסף של this מודגם בשורה 24.
נעתיק שוב הנה את שורות 22-27:
- Example *Example::check_bigger_a(Example &ex){
- if(a > ex.a)
- return this;
- else
- return &ex
- }
בשורות הנ"ל, המתודה משווה בין שני ex.a, כאשר ex הוא אובייקט שמועבר כפרמטר, לבין המשתנה הלוקלי a. במתודה מחזירה את המצביע לאובייקט שה-a שלו גדול יותר.
שורה 3: במקרה שהאובייקט הלוקלי גדול יותר, היא מחזירה את this.
שורה 3: במקרה שהאובייקט הלוקלי גדול יותר, היא מחזירה את this.
ונעבור לפונקציה המפעילה -main. היא מועתקת הנה:
- int main(){
- Example ex1(1,2);
- Example ex2(3,4);
- Example *ex3;
- ex3 = ex1.check_bigger_a(ex2);
- cout << ex3->a;
- }
שורות 2-3: יוצרים שני אובייקטים של Example.
שורה 4: יוצרים pointer מסוג Example.
שורה 5: מפעילים את המתודה check_bigger_a של האובייקט ex1. מכאן ש-this יצביע על ex1.
המצביע של האובייקט שה-data member a שלו גדול יותר, יכנס לתוך ex3.
שורה 6: הדפס את ex3->a. מה יהיה הפלט? התשובה: 3.
אין תגובות:
הוסף רשומת תגובה