(C++) השמדת אובייקט חייבת לגרור שינוי במשתנה סטטי שלו - לא עובד - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

(C++) השמדת אובייקט חייבת לגרור שינוי במשתנה סטטי שלו - לא עובד


judas_clown

Recommended Posts

אהלן,

יש לי מערך דינאמי של אובייקטים שנוצרו לפי קלאס שכתבתי

לכל אחד מהאובייקטים האלה חייב להיות ID (מפתח ייחודי)

את המפתח מימשתי ע"י משתנה סטטי (int) בקלאס, שמאותחל ל-0, ובקונסטרקטור שלו יש קריאה שמגדילה אותו באחד

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

-עד כאן הכל תקין, כל אובייקט מקבל ID עוקב ל ID הקודם.

בדיסטרקטור כתבתי הנחיה להפחית 1 מה-ID הזה,

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

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

למישהו יש מושג איך לעשות כזה דבר?

אם אני מנסה לקרוא ישירות לדסיטרקטור (זה נכון לעשות כזה דבר?)

אז מתאפסים כל המשתנים באובייקט שהם string , אלה שהם int משום מה לא מתאפסים (למה זה קורה בעצם?)

והמשתנה הסטטי שאמור לקטון ב-1 (זה הקוד היחיד שהדיסטרקטור מריץ...) - פשוט לא קטן!

אשמח לכל עצה.

הקוד הרלוונטי מצורף:

קונסטרקטור+רשימת אתחול- עובד אחלה, כל אובייקט חדש אכן מקבל ID גדול ב-1 מזה של האובייקט הקודם, הראשון 0, השני 1 וכו'.


int Song::_idcount=0; //static of Song - ID counter

Song::Song(string title, string artist, string album, int length, int track):
// init list
_id(_idcount),
_title(title),
_artist(artist),
_album(album),
_length(length),
_track(track)
{
_idcount+=1; //incerease the id count for every new object
}

הדיסטרקטור:

Song::~Song()
{
if(_idcount!=0){_idcount-=1;}
}

במיין אני מריץ את הקוד הבא:


Song s("Smells like teen spirit", "Nirvana", "Nervermind" , 473, 2);
Song s1("86","Green Day","Insomniac",152,7);
Song s2("Basket Case","Green Day","Dookie",323,7);

s.Play();
s1.Play();
s2.Play();

s1.~Song();
s1.Play();

כל play מדפיס לפלט את המשתנים של SONG, כולל ה ID

הפלט שאני מקבל הוא כזה:

Playing:

Id: 0
Title: Smells like teen spirit
Artist: Nirvana
Album: Nervermind
Length: 7:53
Track: 2


Playing:

Id: 1
Title: 86
Artist: Green Day
Album: Insomniac
Length: 2:32
Track: 7


Playing:

Id: 2
Title: Basket Case
Artist: Green Day
Album: Dooky
Length: 5:23
Track: 7


Playing:

Id: 1
Title:
Artist:
Album:
Length: 2:32
Track: 7
Press any key to continue . . .

עריכה:

אוקי, הבנתי את הטעות בערך -

הורדתי את _idcount ב-1 אבל לא את _ID שזה המפתח של האובייקט (בעצם צריך להוריד את שניהם)

עכשיו זה עובד - הקאונטר יורד ב1, ואת ה ID של האובייקט עצמו - החלטתי לאתחל למינוס אחד.

השאלה היא איך אני משמיד את האובייקט, הרי מהרגע שהוא יצא מהמערך שלי,

אין לי צורך בו, אבל הוא עדיין תופס בסקופ של התוכנית או הפונקציה

(כי יצרתי אותו במיין, או לצורך העניין בפונקציה כלשהיא שמכניסה אותו למערך)

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

קישור לתוכן
שתף באתרים אחרים

קודם כל, לעולם אל תקרא ל-destructor שלך ישירות.

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

אופציה אחרת היא להכניס את האובייקט לתוך סקופ, כלומר לעטוף את כל קטע הקוד שמתעסק איתו ב-{}.

שמתי לב אבל לבעיה בלוגיקה שלך - נניח שיצרת שלושה אובייקטים - אז המזהים שלהם יהיו 0, 1 ו-2. אם תמחק את אובייקט מספר 1, אז ה-idcount ירד ל-2, ואז כשתיצור אובייקט חדש אז גם הוא יקבל מזהה 2 (ויהיו לך שני אובייקטים עם אותו המזהה).

קישור לתוכן
שתף באתרים אחרים

תודה,

בקשר ללוגיקה-

מכיוון שהאובייקט שמחקתי כבר לא חשוב לרשימת האובייקטים

(מבחינתי הוא מת, בין אם הוא באמת השתחרר מהזכרון ובין אם לאו; בכל אופן הוא לא ברשימת האובייקטים)

אזי האובייקט החדש שיווצר עם ID2, לא יתנגש עם אף אובייקט שקיים ברשימה.

לא מצאתי דרך טובה יותר להקצות ID שונה לכל אובייקט.

אסור ששניים עם אותו ID יהיו ברשימה/מערך ביחד.

קישור לתוכן
שתף באתרים אחרים

אין לך יתרון ב"לחזור אחורה" מבחינת מספרי מספרי האובייקטים. תמשיך לספור קדימה כל הזמן.

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

עם קונטיינר יעיל מספיק, זה לא צריך להיות כבד. אם אתה רוצה גם להיות יעיל מבחינת , אז תשמור בקונטיינר "קטעים" תפוסים, כלומר, טווחים של המפתחות התפוסים, וכשאתה מוחק אובייקט, תפצל את הטווח ל-2, ותחבר ID של כל אובייקט שאתה מוסיף לטווחים לידו, אם הוא צמוד אליהם.

זה קצת יותר קוד, אבל הרבה פחות (אם יש לך הרבה שירים).

וכמובן, כל זה תלוי בכמה שירים אמורים להיות בסה"כ במערכת בזמן נתון. אם לא הרבה - אז תמיד עדיף קוד פשוט על פני קוד יעיל...

עריכה: ואם אתה כבר הולך על האפשרות של "טווחים" אז אפשר לייעל גם את הנושא של חיפוש אם ID מסוים תפוס או לא.

קישור לתוכן
שתף באתרים אחרים

ארכיון

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

×
  • צור חדש...