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

תוכן שנמחק תוכן שנוסף
Ybungalobill (שיחה | תרומות)
Ybungalobill (שיחה | תרומות)
אופרטור קריאה לפונקציה
שורה 166:
 
אופרטורים אלה מועמסים בדומה לשאר האופרטורים שצוינו, אמנם נפרט:
* אופרטור האינדקסציה {{קוד בשורה|[]}} מקבל כפרמטר את האינדקס שיכול להיות כל טיפוס שהוא (למשל מחרוזת, או טיפוס המייצג "טווח" של אינדקסים). כדי שנוכל להשים ערך באמצעות אחד אופרטורי ההשמה, אופרטור זה צריך להחזיר ייחוס לאיזשהו אובייקט.
* את האופרטור {{קוד בשורה|*}} (אונארי) נעמיס בדומה ל-[] למעט ההבדל היחידי שהוא אונרי ולא מקבל פרמטרים.
* האופרטור {{קוד בשורה|->}} הינו אופרטור מבלבל. הסיבה לכך היא שהוא נראה כמו אופרטור בינארי, אומנם אנו מגדירים אותו כאילו שהוא אונרי. אופרטור זה זהה לאופרטור * מלבד התחביר במקום הקריאה.
* אופרטור {{קוד בשורה|&}} (אונארי) מוגדר כברירת מחדל לכל מחלקה, ומשמעותו הרגילה היא "כתובת האובייקט בזיכרון", אומנם ניתן לשנות משמעות ברירת מחדל זו על ידי העמסה.
 
להלן דוגמה של מצביע "חכם" אשר בודק את נכונותו בכל רגע בו אנו מנסים לקרוא או לכתוב למערך אליו הוא מצביע:
שורה 227:
 
=== אופרטור קריאה לפונקציה ===
 
על ידי העמסת אופרטור {{קוד בשורה|()}} נוכל ליצור אובייקט שיתנהג כפונקציה. משמעות הדבר שנוכל לקרוא לפונקציה ששמה הוא האובייקט עצמו. דבר זה שימושי כאשר נרצה לשמור מידע מסויים בין הקריאות לפונקציה. כאשר נשתמש בפונקציות רגילות נעשה זאת בעזרת משתנים סטטיים או גלובליים, לכן לא נוכל לעשות מספר "עותקים של הפונקציה". אומנם אם נגדיר מחלקה ונעמיס עבורה את האופרטור הזה נוכל להשיג את המטרה הרצויה. למשל נוכל ליצור אובייקט לקבלת מספרים פסאודו אקראיים. גישה כזו, בניגוד לכתיבת פונקציה רגילה, תאפשר לתחזק בו-זמנית מספר סדרות אקראיות נפרדות. לדוגמה:
<div style="direction: ltr;"><source lang="cpp">
class randGen {
static const int mul = 1664525;
static const int add = 1013904223;
 
int num;
 
public:
randGen(int seed) : num(seed) {}
 
static const int max = 0x80000000;
int operator () () {
// מחזיר מספר פסאודו אקראי בין 0 לערך המקסימלי
num *= mul;
num += add;
return num & 0x7FFFFFFF;
}
 
int operator () (int x, int y) {
// מחזיר מספר: x <= num < y
return int(double((*this)())/max*(y-x)) + x;
}
};
</source></div>
 
בדוגמה זו ישמנו את אחד האלגוריתמים הנפוצים בישומים פשוטים ליצירת סדרה אקראית, לפרטים [http://en.wikipedia.org/wiki/Linear_congruential_generator כאן] (באנגלית).
 
העמסנו את האופרטור () פעמיים: ללא פרמטרים לקבלת מספר אקראי כלשהו בין 0 ל-max ועם שני פרמטרים לקבלת ממספר אקראי בין x ל-y. עתה נוכל להשתמש בטיפוס זה, נגדיר שני אובייקטים ליצירת שתי סדרות: האחת דטרמיניסטית (עם כל הפעלה של התוכנית היא תהיה זהה) והשנייה פסאודו אקראית המאותחלת באמצעות הטיימר של המחשב:
<div style="direction: ltr;"><source lang="cpp">
randGen detSeq(346); // הסדרה תמיד זהה
randGen randSeq(static_cast<int>(time(0))); // הסדרה תמיד שונה
 
for(int i = 0; i < 5; i++)
cout << detSeq(0, 100) << ", ";
cout << endl;
 
for(int i = 0; i < 5; i++)
cout << randSeq(0, 100) << ", ";
cout << endl;
</source></div>
 
תוכנית זו תדפיס בשורה הראשונה תמיד: {{קוד בשורה|74, 32, 45, 95, 96,}} ואילו אנו לא יודעים מראש מה יופיע בשורה השנייה.
 
=== העמסת new ו-delete ===
 
לעשות
 
{{C++|מוגבל=כן}}