C++/העמסת אופרטורים: הבדלים בין גרסאות בדף

תוכן שנמחק תוכן שנוסף
Ybungalobill (שיחה | תרומות)
אין תקציר עריכה
Ybungalobill (שיחה | תרומות)
אין תקציר עריכה
שורה 93:
& | ^ >> <<
</source></div>
אופרטורים אלה נוכל להגדיר גם כחברי המחלקה וגם כאופרטורים סטטיים (בתוך מרחב שם, כולל גולובלי). כיוון שאופרטורים אלה הם בינאריים הם מקבלים שני אופרנדים. חוק הקיבוץ לא תקף לאופרטורים אלה, אלא אם כן לא נדאג לדבר זה בעצמינו. סדר הקיבוץ של הבטוי שירשור האופרטורים הוא משמאל לימין, כלומר: {{קוד בשורה|(a + b + c)}} זהה ל-{{קוד בשורה|((a + b) + c)}} ולא ל-{{קוד בשורה|(a + (b + c))}}.
 
אם אופרטורים אלה הם חברי מחלקה אז האופרנד הראשון יהיה המופע של המחלקה עבורו נקראת פונקציית האופרטור, ואילו האופרנד השני יתקבל דרך הפרמטר היחידי של אותה הפונקציה. לרוב אופרטורים כאלה לא משנים את האובייקט עצמו אלא מחזירים אובייקט חדש, במקרה זה נגדיר אותם כפונקציות const (אפשר לעשות גם אחרת, אם נרצה למשל ש>> ישנה את האופרנד שלו).
שורה 112:
 
המהדר לא יחליף את סדר האופרנדים מעצמו בשום מקרה, לכן, בהנתן ההגדרות שלמעלה, לא נוכל לכתוב {{קוד בשורה|100/a}}, אולם מותר לכתוב {{קוד בשורה|a/100}}.
 
=== פעולות קלט ופלט ===
 
הספרייה התקנית של C++ (שמה STL) מגדירה את המחלקות istream ו-ostream שמהוות את מחלקות האב (למד הורשה בהמשך) למחלקות רבות אחרות שמאפשרות קלט ופלט. מחלקות לעבודה עם קבצים, למשל, נגזרות ממחלקות אלה. גם טיפוסי האובייקטים cout ו-cin, איתם כבר עבדנו, הם ostream ו-istream בהתאמה. כדי לקלוט ולפלוט משתנים מטיפוסים מובנים אנו משתמשים באופרטורים << ו->> שהם אופרטורים בינאריים המוגדרים בספריית STL. באופן דומה נוכל להעמיס אופרטורים אלה כדי לקלוט מ-istream ולפלוט ל-ostream את הטיפוס שאנו הגדרנו. אופרטור כזה יקבל כאופרנד ראשון את ה-stream ממנו אנו קולטים או אליו אנו פולטים, וכאופרנד שני את האובייקט עצמו. לדוגמה:
<div style="direction: ltr;"><source lang="cpp">
ostream& operator << (ostream& s, const Vector2D &v)
{
s << "(" << v.x << ", " << v.y << ")";
return s;
}
</source></div>
 
אנו החזרנו את s כערך כדי שנוכל לשרשר את הפלט בעתיד. עכשיו נוכל להשתמש באופרטור זה:
<div style="direction: ltr;"><source lang="cpp">
Vector2D pos = {12, 32};
cout << "pos = " << pos << endl;
</source></div>
 
וכתוצאה יודפס: {{קוד בשורה|<nowiki>pos = (12.0, 32.0)</nowiki>}}.
 
=== פעולות לוגיות ופעולות השוואה ===
 
נייחס לקטגוריה זו את הפעולות:
<div style="direction: ltr;"><source lang="cpp">
> >= < <= == !=
&& ||
</source></div>
 
אופרטורים אלה המוגדרים עבור טיפוסים מובנים מחזירים את הטיפוס הלוגי bool. אם נרצה לשמור על בהירות התוכנית ועל משמעותם האגילה, גם אנחנו נגדיר אותם באופן זה, אלה אם כן נרצה לשנות את משמעות זו.
 
אופרטורים אלה ניתן להגדיר גם כחברי מחלקה וגם כפונקציות סטטיות. גם להם שני אופרנדים. סדר הקיבוץ גם כאן הוא משמאל לימין: {{קוד בשורה|(a && b && c)}} זהה ל-{{קוד בשורה|((a && b) && c)}}.
 
לדוגמה:
<div style="direction: ltr;"><source lang="cpp">
bool operator == (const Vector2D &a, const Vector2D &b)
{
return a.x == b.x && a.y == b.y;
}
</source></div>
 
''הערה:'' בעבודה עם נקודה צפה יש לעשות השוואה עם epsilon עקב אי-דיוק ועיגול התוצאות.
 
=== פעולות השמה ===
 
נייחס לקטגוריה זו את הפעולות:
<div style="direction: ltr;"><source lang="cpp">
= *= /= %= += -= <<= >>= &= |= ^=
</source></div>
 
כיוון שהמשמעות המקורית של אופרטורים אלה היא לבצע שינוי באופרנד השמאלי, אופרטורים אלה צריכים להיות מוגדרים בתוך המחלקה. דבר זה מבטיח שהאופרנד השמאלי ימצא בזיכרון (יהיה lvalue), ומסיבה זו לפונקציות האופרטורים האלה יהיה תמיד רק פרמטר אחד (האופרנד הימני). סדר קיבוץ פעולות אלה הוא מימין לשמאל: {{קוד בשורה|<nowiki>(a = b = c)</nowiki>}} זהה ל-{{קוד בשורה|<nowiki>(a = (b = c))</nowiki>}}.
 
=== פעולות אונריות ===