בעיה | בעיה בדריסת פונקציות וירטואליות
-
רבותי אני כמעט משתגע
שעות אני תקוע על הבאג המוזר הזה (זכור לי שנתקלתי בזה פעם ולא הצלחתי לפתור את זה)
שאלתי את גוגל ואת הרובוט ואין לאל ידם לעזור לי
ובכן עשיתי מחלקת בסיס כזאת:class MGIIunknown { public: /// <summary> /// Get the special ID to the class /// </summary> /// <returns>UINT, the id of this class</returns> virtual unsigned int GetClassCode() = 0; /// <summary> /// Query Operation that checks whether the current /// class or one of the parent classes matches the /// code entered as a parameter /// </summary> /// <param name="classCode">The specific id</param> /// <returns>bool, If a match is found</returns> virtual bool QueryClassCode(unsigned int classCode) = 0; };המשמשת כבסיס למחלקות נגזרות, שעל ידה אפשר לקבל מידע על המחלקה
כעת המחלקה הנגזרת מקבלת קוד כזה:
class MGIIobject : public MGIIunknown { public: MGIIobject(); ... other functions // unknown implementation virtual unsigned int GetClassCode() { return OBJECT_CODE; } virtual bool QueryClassCode(unsigned int classCode) { if (classCode == GetClassCode() || classCode == UNKNOWN_CODE) return true; return false; } };וכל מחלקה הנגזרת מMGIIobject מקבלת קוד כזה:
virtual unsigned int GetClassCode() { return CLASS2_CODE; } virtual bool QueryClassCode(unsigned int classCode) { if (classCode == GetClassCode()) return true; return MGIIobject::QueryClassCode(classCode); }וכן הלאה מחלקות שנגזרות מMGIclass2 (לשם הדוגמה)
כעת אני קורא למחלקה לא ידועה (שיורשת מMGIIunknown) כך (המחלקה FOO לשם הדוגמה):
MGIIunknown & obj = *((MGIIunknown*)(values[i])); bool is_foo_class = obj.QueryClassCode(FOO_CODE)וקורה דבר מטורף כזה:
התוכנה כביכול מתבלבלת ובמקום לגשת לפונקציה obj.QueryClassCode היא קוראת לפונקציה אקראית במחלקה FOO ומחזירה תוצאה בלי קשר
זה נראה כאילו יש איזה באג בטבלת הכתובות שהשם של הפונקציה מצביע על מחלקה אחרת
מה עושים למען ה'?
בתודה מראש וסליחה על האריכות -
רבותי אני כמעט משתגע
שעות אני תקוע על הבאג המוזר הזה (זכור לי שנתקלתי בזה פעם ולא הצלחתי לפתור את זה)
שאלתי את גוגל ואת הרובוט ואין לאל ידם לעזור לי
ובכן עשיתי מחלקת בסיס כזאת:class MGIIunknown { public: /// <summary> /// Get the special ID to the class /// </summary> /// <returns>UINT, the id of this class</returns> virtual unsigned int GetClassCode() = 0; /// <summary> /// Query Operation that checks whether the current /// class or one of the parent classes matches the /// code entered as a parameter /// </summary> /// <param name="classCode">The specific id</param> /// <returns>bool, If a match is found</returns> virtual bool QueryClassCode(unsigned int classCode) = 0; };המשמשת כבסיס למחלקות נגזרות, שעל ידה אפשר לקבל מידע על המחלקה
כעת המחלקה הנגזרת מקבלת קוד כזה:
class MGIIobject : public MGIIunknown { public: MGIIobject(); ... other functions // unknown implementation virtual unsigned int GetClassCode() { return OBJECT_CODE; } virtual bool QueryClassCode(unsigned int classCode) { if (classCode == GetClassCode() || classCode == UNKNOWN_CODE) return true; return false; } };וכל מחלקה הנגזרת מMGIIobject מקבלת קוד כזה:
virtual unsigned int GetClassCode() { return CLASS2_CODE; } virtual bool QueryClassCode(unsigned int classCode) { if (classCode == GetClassCode()) return true; return MGIIobject::QueryClassCode(classCode); }וכן הלאה מחלקות שנגזרות מMGIclass2 (לשם הדוגמה)
כעת אני קורא למחלקה לא ידועה (שיורשת מMGIIunknown) כך (המחלקה FOO לשם הדוגמה):
MGIIunknown & obj = *((MGIIunknown*)(values[i])); bool is_foo_class = obj.QueryClassCode(FOO_CODE)וקורה דבר מטורף כזה:
התוכנה כביכול מתבלבלת ובמקום לגשת לפונקציה obj.QueryClassCode היא קוראת לפונקציה אקראית במחלקה FOO ומחזירה תוצאה בלי קשר
זה נראה כאילו יש איזה באג בטבלת הכתובות שהשם של הפונקציה מצביע על מחלקה אחרת
מה עושים למען ה'?
בתודה מראש וסליחה על האריכותטוב, בסוף הGPT שלף את הקסם מהכובע:
הפתרון האמיתי:אסור לעשות cast כזה!
אם אתה יודע שהאובייקט הוא ממשפחת MGIIunknown → השתמש ב־dynamic_cast:
MGIIunknown* obj = dynamic_cast<MGIIunknown*>(values[i]); if (obj) { bool is_foo_class = obj->QueryClassCode(FOO_CODE); }בכל אופן תודה על הרצון הטוב