שאלה ב C++

vinney

Well-known member
אוי ואבוי לי...

אופרטורים >> ו << משמשים ב++C לעבודה עם STREAMים. מה שאתה עשית טכנית אפשרי, אבל שוב - לא יפה, שובר את כל הסטנדרטים, ובלי שום הצדקה בכלל. גם אם אתה כותב משהו שרק אתה תשתמש בו, תכתוב את זה לפי הספר, לא איך שבא לך, ולו מהסיבה הפשוטה שתתרגל לכתוב ככה ובסוף תכתוב כך גם בעבודה/במוצר שתחליט למחור. הכתיבה הזאת לא נכונה, מקור לבאגים, לא עושה את מה שהתכוונת שתעשה, אלא את מה שהקומפיילר חושב שהתכוונת, ולא ניתנת לשימוש חוזר - אתה עצמך לא תבין מה עשית פה עוד חודשיים. לגבי כן << ולא >> - למה? אתה תמיד שומר את האובייקט, אבל אף פעם לא משחזר אותו מהשמור?
 

1אברהם

New member
../images/Emo4.gif

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

vinney

Well-known member
לא!

אתה לא מבין! לא משתמשים בפוינטרים ! לא משתמשים בהעתקה ביט לביט, לא משתמשים בהשמה של THIS - אתה עובד בתכנות פרוצדורלי ב++C! זה לא נכון וזה לא יעיל, אתה תכתוב המון קוד מיותר! תקרא על STREAMים של ++C, תקרא על SERIALIZATION של MFC (שמתשמשת בSTREAMים), תקרא על COPY CONSTRUCTORS, תקרא על OPERATOR OVERLOADING ותקרא על IO ב++C וספריות STL באופן כללי. בלי זה - אתה תעבוד המון, ולחינם.
 

voguemaster

New member
עצה קונסטרוקטיבית

אני לא יודע מה אתה כותב אבל הרעיון של "לשפוך" תוכן של באפר לתוך איזור בזיכרון כדי להפוך אותו לאובייקט הוא מתכון לצרות, בטח אם מה שאתה קורה מגיע מתוך קובץ. אין לך שום sanity checks על הקלט וזה איך נגיד... מסוכן כמו לנסוע 200 בתוך העיר
 

1אברהם

New member
תודה על העצה, אבל זה יותר אזהרה

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

voguemaster

New member
שתבין

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

1אברהם

New member
טוב

לגבי Serialization לא היכרתי ואני צריך ללמוד את זה ( תודה שיידעת אותי על האפשרות הזו ) היתרון בשיטה שלך שעוטפים את הmembers ברי ההיתחול ב struct ורק אותו מהתחלים, מצד שני זה נראה לי יותר מסורבל כי כדי לגשת ל member צריך לעבור דרך התיווך של POD_Data למשל במקום לכתוב data1=17 צריך לכתוב POD_Data.data1=17 . אבל עדין אני לא מבין מה יש לכם נגד ההשמות
*this=*((B*)p); *((B*)p)=*this;​
הרי זה השמות בין אוביקטים וזה מוגדר היטב בשפה שברירת המחדל היא העתקה ביט לביט
 
העתקה ביט לביט מסוכנת

פתח ספר לימוד טוב ב++C וקרא את הפרק על Copy Constructor, תוכל למצוא שם הסברים ודוגמאות מדוע העתקה ביט-ביט מסוכנת.
 
והנה דוגמה:

יש לך פוינטר באובייקט A. הקצאת אותו דינאמית. העתקת אותו bitwise לאובייקט B. עכשיו גם הפוינטר ב B מצביע לאותה כתובת. אם תשנה אותו ב A תשנה אותו גם ב B ולהיפך. זה מה שאתה רוצה? יותר גרוע, נניח שה destructor של B נקרא (ולא הפכת את הפוינטר ל NULL) מה שהפוינטר מצביע עליו - נמחק. כשתנסה להרוס את A - תנסה לעשות DELETE למשהו שלא קיים => segmentation fault. לכן לא עושים דבר כזה.
 
למעלה