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

בדיקת טיפוסים בזמן ריצה ב-C++


MiniMizer

Recommended Posts

m_dishBoxes זה אכן וקטורים של וקטורים.

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

for ( int generalCounter=0, innercouner=1; counter <= m_dishBoxes.size(); counter++ )
{

if ( (m_dishBoxes[generalCounter][innercouner])->isSameType( dish ) )
{
m_dishBoxes[generalCounter]->pushback(dish);
break;
}

}

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

  • תגובות 45
  • נוצר
  • תגובה אחרונה

איפה אתה מקדם את generalCounter?

חוץ מזה, מה עם אחד מהוקטורים שב-m_dishBoxes ריק? זה יגרום לשגיאה.

אתה חייב לשמור איפשהו אובייקט אחד מכל טיפוס שיורש מ-Dish (זה יהיה אובייקט "dummy", כלומר לא איכפת לך ממה שהוא מכיל, אלא רק מהטיפוס שלו).

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

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

if ( m_dishBoxes.empty() )
{
m_dishBoxes[1].pushback(dish);
}
else
{
for ( int generalCounter=0, innercounter=1; generalCounter <= m_dishBoxes.size(); generalCounter++ )
{

if ( (m_dishBoxes[generalCounter][innercounter])->isSameType( dish ) )
{
m_dishBoxes[generalCounter]->pushback(dish);
break;
}
else
{
m_dishBoxes[generalCounter+1]->pushback(dish);
break;
}

{
}

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

יש פה המון סתירות. אתה מתבלבל בין הוקטור m_dishBoxes לבין הוקטורים שהוא מכיל.

לדוגמה, ה-if הראשון בודק אם הוקטור m_dishBoxes ריק. אם הוא ריק, אז אתה לא יכול לגשת אליו בכלל (כלומר [m_dishBoxes[1 חורג מהגבולות שלו).

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

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

זה לא יעבוד, ה-else שלך מנסה לדחוף פוינטר לאובייקט לתוך וקטור שלא בטוח שקיים בכלל (generalCounter+1 - מאיפה לך שיש שם תא בכלל?).

מה גם שהבדיקה של הכלי צריכה להיות מול וקטור CorrectDishes ולא מול m_dishBoxes...

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

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

minimizer רשם "מה גם שהבדיקה של הכלי צריכה להיות מול וקטור CorrectDishes ולא מול m_dishBoxes..."

רציתי רק להגיד שאת הבדיקה אם הכלי נכון או לא ביצעתי כבר לפני פשוט לא צירפתי את הקוד. מה שצירפתי מתבצע למעשה במידה והכלי אכן תקין.

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

שניצל, זה חלק מתרגיל הבית (שמשותף לשנינו מסתבר :)).

יש וקטור שנקרא CorrectDishes שבתוכו מאוחסנים אובייקטים ספציפיים. כל אובייקט נוסף ש"נקלט" במערכת אמור להבדק האם הוא תואם לאובייקטים שנמצאים בוקטור CorrectDishes (על פי כל מני פרמטרים, כשאחד מהם זה הטיפוס שלו - הסיבה שלשמה פתחתי את הת'רד הזה מלכתחילה).

אם הוא תואם במדויק לאחד מהם, אזי צריך לשים אותו בתוך וקטור נפרד - ואת הוקטור הנפרד הזה לדחוף לתוך הוקטור של dishBoxes.

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

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

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

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

זה למה רשמתי את השורה הזאת:

 m_dishBoxes[generalCounter][innercounter])->isSameType( dish )

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

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

חשבתי להתערב פה קצת, ולהעיר עמה הערות כלליות על מה שכתבו כאן עד עכשיו, וכך לתרום את תרומתי לשלום העולם או לפחות לקוד נקי מבאגים:

1) בתוכנה גדולה ורצינית, עדיף להשתמש ב-RTTI המובנה בשפה ולא לכתוב אחד משלכם עם enum-ים. הקומפיילר יודע לעשות את זה מצויין, יעיל, ועם הרבה פחות באגים. בדיוק מאותה סיבה אתם משתמשים ב-virtual function וירושה במקום לממש בעצמכם function tables וירושה עם struct-ים.

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

2) ממה שהתרשמתי, התכנון (ואולי עצם הגדרת התרגיל) מגדירים מבנה תוכנה שנחשב היום גרוע ומעוות. יקח הרבה יותר זמן להסביר בדיוק למה אני מתכוון ולכן אני רק ארשום נקודות:

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

* נראה שהפתרון צועד לכיוון cosmic hierarchy, שיטה שבאמצע שנות התשעים התחילו להבין שב-C++ היא בעייתית. היא מעודדת דברים כמו heterogeneous containers ואינספור switch-ים ובדיקות טיפוסים, אשר גורמים לבאגים וקשיי תחזוקה. תלוי במשימה כמובן, אבל הרבה פעמים אפשר וכדאי לתכנן את היררכית האוביקטים ואת התוכנה אחרת.

3) חלק מהבעיות שאתם מנסים לפתור (לדוגמא operator==) נובעות מתכנון ההירכיה שלכם.

כמובן כמו כל ההמלצות, יש מצבים שבהם כמובן ההמלצות הנ"ל לא נכונות.

באמת קטונטי מלהסביר את כל זה ולכן אני אשלח את כולם לקרוא את Scott Meyers (הספרים הם ++effective c וכן ++more effective C). עוד כדאי לקרוא את herb sutter, ואת C++ report וכמובן לחפש את הנושאים באינטרטרון.

http://www.ddj.com/cpp/184401613

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

ארכיון

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


×
  • צור חדש...