פונקציה חברה לדוגמא

פונקציה חברה לדוגמא

לגבי הפונקציה החברה המופיעה בהגדרת המחלקה הבאה:
קוד:
class Point
{
	int x, y;
public:
	Point(int x = 0, int y = 0) : x(x), y(y) {}

bool equals(const Point& other) const
{
cout << "In Point::equals\n";
return x == other.x && y == other.y;
}

friend bool equalPoints(const Point& p1, const Point& p2) 
{
cout << "In equalPoints(global)\n";
return p1.x == p2.x && p2.y == p2.y;
}
};

למה בעצם חשוב להגדיר את פונקציה כפונקציה חברה? מה היה קורה אם היא לא הייתה חברה?
 

BravoMan

Active member
היית מקבל שגיאת קומפילציה!

חבל שאתה ישר רץ לפורום במקום לבדוק בעצמך.
זה קוד שיכולת לקמפל, וללמוד מהודעת השגיאה שלו.
&nbsp
אולי דילגת על זה, או אולי שכחת, אבל ב-++C, אם אתה לא מציין הרשאת גישה של איבר מחלקה או מתודה, ברירת המחדל היא private.
כלומר, רק למתודות של Point יש רשות לגשת ל-x ו-y.
 

BravoMan

Active member
אני חושב שהבנתי מה מבלבל אותך:

הקוד הזה לא כתוב טוב בתור דוגמה.

אם תוריד את המילה friend הוא עדיין יתקמפל, ואפילו הפונקציה תעבוד, אבל אם יש לך קוד אחר שקורא לפונקציה הוא ישבר.

כדי שתבין את הדוגמה, הקוד צריך להראות כך:
קוד:
class Point
{
    int x, y;
public:
    Point(int x = 0, int y = 0) : x(x), y(y) {}

    bool equals(const Point& other) const
    {
        cout << "In Point::equals\n";
        return x == other.x && y == other.y;
    }

    friend bool equalPoints(const Point& p1, const Point& p2);
};

bool equalPoints(const Point& p1, const Point& p2)
{
    cout << "In equalPoints(global)\n";
    return p1.x == p2.x && p2.y == p2.y;
}

int main(int argc, char **argv) {
    Point p1, p2;

    cout << equalPoints(p1, p2);

    return 0;
}
בדוגמה כתבו את equalPoints בתוך גוף המחלקה, אבל היא למעשה פונקציה חיצונית, שאתה מפעיל בלי אובייקט של מחלקה.

בתור פונקציה חיצונית, אין לה אפשרות גישה לאיברים פרטיים, אלא אם מכריזים עליה כ-friend.

הדוגמה מטעה קצת בכך שהיא גורמת ל-equalPoints להראות כמו עוד מתודה בדומה ל-equals.
 

BravoMan

Active member
אתה לא רואה שהפונקציה ניגשת לאיברים x ו-y של Point?

אלה איברים פרטיים ששום פונקציה מחוץ למחלקה לא יכולה לגעת בהם.
&nbsp
קח את דוגמת הקוד שהבאתי לך, תוריד את השורה עם friend ותנסה לקמפל.
תראה מה קורה.
&nbsp
שחק עם זה - ככה לומד מי שבאמת רוצה להיות מתכנת!
 

BravoMan

Active member
בגלל זה בדוגמה שלי כתבתי אותה בחוץ, כדי להראות לך שהיא לא

שייכת למחלקה.
&nbsp
לפי סינטקס של ++C, שיכול להיות מבלבל לפעמים, ניתן לכתוב את כל גוף הפונקציה בתוך גוף המחלקה, והמילה השמורה friend תהיה הדבר היחיד שהלכה למעשה יוציא אותה החוצה.
&nbsp
שים לב שלא כתבתי Point::equalPoints כשכתבתי את קוד הפונקציה.
&nbsp
הסיבה שהשורה עם friend עדיין נמצא בתוך המחלקה, היא שכדי שהפונקציה תהיה "חברה" של מחלקה, המחלקה צריכה להכריז עליה ככזו.
&nbsp
אם כל פונקציה יכלה להחליט שהיא חברה של מחלקה כלשהי בלי שינוי במחלקה עצמה, private היה חסר משמעות, ויכולת "לפרוץ" לתוך כל מחלקה, (אפילו אם אין לך את הקוד המלא שלה).
&nbsp
תחשוב על זה כך:
בחיים האמתיים, אתה מחליט שיוסי הוא חבר שלך, ולא יוסי מחליט שאתה רואה בו חבר על דעת עצמו.
 

computer helper

New member
לא נראה לי שחשוב

קצת נראה מיותר לעשות את זה בצורה של פונקציה מחוץ למחלקה. בעיקרון אתה מעדיף שפונקציות מבחוץ לא יגעו לך בשדות הפרטיים של המחלקה. זה עקרון חשוב ש friend שובר
לפעמים אין ברירה כמו בהעמסת אופרטורים מסויימים כמו
operator<<(ostream&, my_type const &)
שאם תשים במחלקה הוא מקבל כפרמטר ראשון this. ואתה לא רוצה את זה
 
למעלה