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

תוכן שנמחק תוכן שנוסף
Ybungalobill (שיחה | תרומות)
מ תיקון משני שני
Ybungalobill (שיחה | תרומות)
שורה 275:
האופרטורים new ו-delete המוגדרים כברירת מחדל, מקצים זיכרון מאיזושהי ערימה הניתנת על ידי המערכת. לרוב זוהי אותה הערימה בה משתמשות הפונקציות ממשפחת malloc ב-C. בתוכנות גדולות נרצה לעיתים להעמיס את האופרטורים new ו-delete, בעיקר כדי לשפר את הביצועים של התוכנה על ידי שימוש ב-pools או על ידי הקצאת זיכרון בשיטה אחרת כלשהי (מעירמה המיוחד שלנו למשל).
 
ניתן להעמיס אופרטורים גלובליים להקצאת זיכרון, למשל אם נרצה לחפש דליפות זיכרון. כותרות הפונקציות המתאימות הן:
בחלק זה נדגים כיצד להעמיס את האופרטורים האלה, ובשביל הפשטות נשתמש ב-malloc להקצאת הזיכרון.
<source lang="cpp">
<span style="color: red;">'''להוסיף דוגמה'''</span>
void* operator new (size_t s)
void operator delete (void* p);
void* operator new[] (size_t s);
void operator delete[] (void* p);
</source>
פונקציות אופרטורי ה-new מקבלות כפרמטר את נפח הזיכרון הדרוש ועליהם להחזיר את כתובת האזור שהוקצה. אם אין אפשרות להקצות את הזיכרון, נוכל להחזיר 0 או לעורר חריגה. פונקציות אופרטורי ה-delete מקבלות את כתובת הזיכרון אותו יש לפנות. אופרטורים אלה עובדים עם זיכרון לא מאותחל, את הקריאה לבנאי מוסיף המהדר לאחר ש-new מחזירה את הזיכרון ואילו את הקריאה למפרק לפני הקריאה ל-delete.
 
לפעמים אין ברצוננו להחליף את האופרטורים התקניים אלא להעמיס גירסות משלנו. לצורך זה נוכל להוסיף פרמטרים נוספים לגודל הזיכרון ב-new ולכתובת הזיכרון ב-delete. מספר הפרמטרים לא מוגבל ובאפשרותנו לבחור אותם כרצוננו:
<source lang="cpp">
void* operator new (size_t s, const char* str);
void operator delete (void* p, const char* str);
</source>
כדי להשתמש באופרטורים אלה נקרא להם כך:
<source lang="cpp">
class T { /* ... */ };
 
// האופרטורים הגלובליים התקניים
T *stdNew = new T;
delete stdNew;
 
// האופרטורים שלנו
T *myNew = new("1") T;
myNew->~T(); // יש לקרוא למפרק
operator delete(myNew, "2"); // פינוי זיכרון
 
void *myNew2 = operator new(8, "3");
// זיכרון לא מאותחל - אין בנאים ואין מפרקים
operator delete(myNew2, "4");
</source>
 
שימו לב שאין לנו אפשרות לקרוא לאופרטור delete המתאים באותו אופן כמו שקראנו ל-new בהקצאת myNew, עלינו לעשות זאת במפורש. כאשר אנו קוראים לפונקציית האופרטור ללא שימוש באופרטור עצמו, לא מופעלים הבנאים והמפרקים, לכן עלינו לדאוג לדבר זה בעצמנו.
 
ההמשך יבוא...
{{C++|מוגבל=כן}}