עבור לתוכן

שאלה לגבי העמסת אופרטורים ב++C

Featured Replies

פורסם

בקוד הבא:

#include <iostream>
using namespace std;


class A{
int i;
public:
A(int ii = 0) : i(ii) {}
const A& operator+(const A& a) const{
return A(this->i + a.i);
}
const A& operator-(const A& a) const{
return A(this->i - a.i);
}
friend ostream& operator<<(ostream& out, const A& a){
out << a.i;
return out;
}
};


void main(){
A a(5), b(3), c(7);
cout << a + b - c;
}

בmain, פעולת החיבור מתנהגת כצפוי ומחזירה אובייקט A עם שדה i=8. אבל פעולת החיסור מתנהגת כאילו האופרנד השמאלי לא מאותחל בכלל.

איפה יכולה להיות הטעות בקוד שלי?

פורסם

תוריד את האמפרסנד בהחזרות של שני האופרטורים

פורסם
  • מחבר

תודה, זה עבד. יצאתי קצת טמבל שניסיתי להשתמש ברפרנס לאובייקט "מת" אבל לא משנה עכשיו :smile1:

מה שכן מוזר בעיניי זה שהאובייקט היה עדיין בחיים כשהקריאה לa + b חזרה. אפשר בבקשה להסביר את הנקודה הזאת?

פורסם

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

כשמסתיימת הפונקציה, המקום במחסנית "משתחרר", אבל לא נמחק. כלומר, המידע עדיין ישאר שם כל עוד לא ידרכו עליו. ברגע שקוראים לפונקציה נוספת (במקרה הזה האופרטור מינוס) אז המקום במחסנית נדרס.

פורסם
  • מחבר

תודה רבה.

  • 2 שבועות מאוחר יותר...
פורסם
  • מחבר

יש לי שאלה דומה לגבי חריגות. קראתי כאן שצריך לזרוק חריגות by value ולתפוס אותן by reference.

אבל אובייקט החריגה מיוצר על המחסנית, לא? למה במקרה שלו המקום על המחסנית לא משתחרר?

פורסם

בחריגות כל העסק קצת שונה. כשאתה זורק חריגה אז היא מועתקת למקום אחר בזכרון ומשם תופסים אותה. כשאתה אותה catch, אז אם תפסת by value אז החריגה מועתקת שוב לתוך המחסנית של הפונקציה הנוכחית, ואם תפסת by reference אז לא (כלומר משתנה החריגה יצביע על אותו מקום שבו יושבת החריגה שהועתקה). בגלל זה גם אומרים להשתמש ב-throw במקום throw e בשביל זריקה חוזרת, כי השני יגרור העתקה נוספת של החריגה בעוד שהראשון לא.

אתה מוזמן לנסות לכתוב בעצמך קוד בדיקה, ולהדפיס את המקומות בזכרון שבהם יושבת החריגה (כזשזורקים אותה וכשתופסים אותה).

פורסם
  • מחבר

אוקיי הנושא יותר ברור לי עכשיו. תודה רבה.

פורסם

הסיבה שמנסים למנוע העתקות זה לא לביצועים אלא כדי למנוע slicing.

נניח אתה תופס exception מסוג E.

מישהו אחר יצר מחלקה F שיורשת מ-E, אולי ללא ידיעתך, ואז זרק F.

כאשר אתה תופס by value, רק חלק מהנתונים מועתקים נכון לאובייקט החדש מסוג E. זה נקרא slicing, כי בעצם חתכת את האובייקט המקורי.

כאשר אתה תופס by reference, אז הרפרנס מבציע ל-F המקורי. וכאשר תזרוק אותו מחדש עם throw, אז גם כן יזרק המקורי - וכך מישהו מעליך יוכל לתפוס את F ולטפל בו נכון.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים