פונקציה הורסת Destructor
כשם שפונקציה בונה מופעלת אוטומטית כשנוצר אובייקט, כך פונקציה הורסת מופעלת אוטומטית כשאובייקט מת.מתי אובייקט מת? כמו כל משתנה:
• כשיוצאים מהבלוק שלו (לדוגמה יוצאים מהפונקציה שיצרה אותו).
• כמשחררים אותו מהזיכרון הדינאמי.
- שם הפונקציה ההורסת זהה לשם המחלקה. אבל בתוספת התו ~ לפניו.
- התחביר זהה לזה של פונקציה בונה, לכן לא נמצא שום "סוג ערך מוחזר" לפני שם הפונקציה. גם לא void.
- לא מקבלת ולא מחזירה נתונים. לכן לעולם לא תהיה יותר מפונקציה הורסת אחת במחלקה.
- תפקידה להשמיד את האובייקט (דבר שלפעמים נחוץ).
- בשפת ++C אין חובה לכתוב פונקציה הורסת. בין אם יש ובין אם אין פונקציה בונה.
בתוכנית הבאה נרצה לשמור את שם העובד במינימום מקום הדרוש.
הבעיה היא שבסיום התוכנית צריך לשחרר את הזיכרון שהוקצה:
כפי שרואים זה לא חוקי משום שהמשתנה name נמצא בתחום ה private.#include <iostream> #include <string.h> using namespace std; class worker { char *name; int age; public: worker(char *n , int a) { name = new char[strlen(n) + 1]; // לא החשיב strlen המסיים ש NULL ה 1+ זה עבור ה strcpy(name, n); age = a; } }; void main() { worker w1("Shalom" , 38);delete[] w1.name;// לא חוקי }
לא סביר לשים את כל המשתנים שעומדים לעבור הקצאות דינמיות באזור ה public. גם לא סביר לשחרר באופן ידני כל
אובייקט ואובייקט בסיום השימוש בו, משום שהקוד יצא מאוד ארוך, וגם משום שאולי נשכח לשחרר את חלקם.
לכן:
#include <iostream> #include <string.h> using namespace std; class worker { char *name; int age; public: worker(char *n , int a) { name = new char[strlen(n) + 1]; strcpy(name, n); age = a; } ~worker() { delete [] name; } }; void main() { worker w1("Shalom" , 38); }זה שימוש מעולה בפונקציה הורסת.
פרט נוסף (ולא מאוד חשוב)
כאשר נגמרת פונקציה וכל האובייקטים מושמדים, הם מושמדים בסדר הפוך מסדר יצירתם. כלומר הראשון שנוצר הוא האחרון שמושמד.
לדוגמה:
#include <iostream> #include <string.h> using namespace std; class worker { char *name; int age; public: worker(char *n , int a) { name = new char[strlen(n) + 1]; strcpy(name, n); age = a; } void show() { cout<<"Name: "<<name << " Age: " << age<<"\n"; } ~worker() { cout<<"\nDistructing "<<name <<"\n"; // עבור בדיקת סדר ההשמדה delete [] name; } }; void main() { worker w1("Shalom" , 38), w2("Shlomo" , 66), *p; w1.show(); w2.show(); p = new worker("Bibi" , 88); // כאשר פונקציה בונה מקבלת ערכים, זה התחביר בהקצאה הדינמית p->show(); delete p; // p כאן מופעלת הפונקציה ההורסת של }
הפלט יהיה:
שאלות:
שאלה 1:
הגדר מחלקה אשר מכילה מצביע לתחילת מערך arr , וגודל המערך size.
הגדר בנוסף הפונקציות הבאות:
- פונקציה בונה אשר מקבלת מהמשתמש את כמות איברי המערך, מקצה מקום בזיכרון וקולטת את איברי המערך.
- פונקציה בונה אשר מקבלת מצביע לתחילת מערך המסתיים בערך –1 , מקצה מקום ומאתחלת את הנתונים של האובייקט.
- הפונקציה show.
- פונקציה אשר מקבלת עוד איבר ומוסיפה אותו לסוף המערך.
- פונקציה הורסת אשר משחררת את הזיכרון.
ב- main יש להגדיר אובייקט ומצביע לאובייקט, ולהפעיל את הפונקציות השונות.
שאלה 2:
הגדר מחלקה בשם point המייצגת נקודה.
היא מכילה פונקציה בונה והפונקציה show .
הגדר מחלקה נוספת אשר מייצגת מצולע.
היא מכילה מצביע ל- point ומשתנה שלם אשר מייצג את כמות הנקודות.
יש להגדיר את הפונקציות הבאות:
- פונקציה בונה אשר קולטת את מספר הנקודות של המצולע, ובהתאם מקצה מקום בזיכרון.
- הפונקציה show.
- פונקציה למציאת היקף המצולע.
- פונקציה למציאת שטח המצולע. (לא חובה. *)
- פונקציה הורסת לשחרור הזיכרון.
ב- main יש להגדיר אובייקטים ומצביע לאובייקט, ולהפעיל את הפונקציות השונות.
* נסו לחלק את המצולע למשולשים. צאו מנקודת הנחה שצורת המצולע היא "עיגולית", כלומר אפשר למתוח קו ישר מכל קודקוד אל כל קודקוד מבלי שהקו יחתוך את צלעות המצולע.
לצורך מציאת שטח משולש השתמשו ב"נוסחת הרון".
שאלה 3:
הגדר מחלקה אשר מייצגת בן אדם (person).
נתוני המחלקה יהיו:
מצביע לשם ולשם משפחה. ומשתנה לגיל.
היא מכילה פונקציה בונה (שקולטת), פונקציה הורסת והפונקציה show להצגת הנתונים.
הגדר מחלקה אשר מייצגת קבוצת חברים.
נתוני המחלקה יהיו:
כמות החברים ומצביע מסוג person (עבור המערך הדינמי).
יש להגדיר את הפונקציות הבאות:
פונקציה בונה, פונקציה הורסת, הפונקציה show ופונקציה שמחזירה את ממוצע הגילאים.
תשובות:
בהצלחה!
אין תגובות:
הוסף רשומת תגובה