יצירת אובייקטים ממחלקות יורשות ב C++

tberger

New member
יצירת אובייקטים ממחלקות יורשות ב C++

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

קצת ארוך אבל מקווה שהבנתם.
תודה מראש.
 
ובכן

1. אתה יוצר באופן דינמי. למשל, אם ע"פ הקלט צריך ליצור A, אתה עושה new A. (כמובן, צריך לשים את זה במצביע למחלקת הבסיס).
2. לא הבנתי את השאלה. איך אתה שומר מחלקה במשתנה? מה הכוונה "למחלקת ביניים אין סוג"? נראה לי שהכי פשוט יהיה אם תיתן דוגמת קוד (עם הערות במקומות שבהם אתה לא בטוח מה צריך לעשות).
 

tberger

New member
יצירת אובייקטים ממחלקות יורשות ב C++

קודם כל תודה.
לגבי 1: כן זה ברור אבל נניח ויש 10 מחלקות יורשות ברמה שנייה או שלישית מהן יוצרים אוביקטים על פי קלט. איך בוחרים איזו מחלקה? האם רק בעזרת IF או שיש דרך אחרת?
2. אכתוב קוד עוד מעט.

תודה
 

selalerer

New member
אתה מכניס אותנו באמצע מה שעשית שהבסיס שכתבת הוא כבר לא נכון.

מחלקת בסיס לא מודעת למה שקורה מתחתיה. זאת לא האחריות שלה.
לפעמים היא מכינה תשתית לשימוש המחלקות היורשות.
לא צריך להיות לך משתנה במחלקת הבסיס שאומר לך מי היורש.
&nbsp
אולי אם תתאר יותר את הבעיה שאתה מנסה לפתור נוכל להציע פתרון נכון יותר
 

tberger

New member
דוגמא לבעיה

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

מקווה שזה יותר ברור.
תודה
 

tberger

New member
איך יודעים מאיזה סוג האוביקט?

אני שומר פוינטרים בוקטור.
איך יודעים מאיזה class האוביקט בלי type?
 
אם אתה צריך לדעת במפורש, אתה כנראה עושה משהו שגוי.

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

tberger

New member
זו בדיוק הבעיה

אני משתמש ב ENUM ל types אבל יש ENUM רק לצורות הסופיות(למשל משולש ישר זווית) ולא לצורות ביניים (משולש כללי) ולכן לא יכול להפעיל את הבנאי של צורה ממחלקת הביניים.
השאלה היא מה הפתרון?
האם חייבים להפעיל בנאי של צורה ממחלקת ביניים?
אולי לתת ערך ברירת מחדל ל type בבנאי של צורה.
אולי להוסיף ערך ב ENUM.
מחלקת הביניים היא אבסטרקטית (עם Virtual=0).
 

selalerer

New member
למה אתה צריך לדעת?

אם יש לך קוד ששואל את זה, רוב הסיכויים שהבעיה שם ואת זה צריך לתקן.
&nbsp
בכל מקרה משתנה type לא צריך
 

tberger

New member
דוגמא מורכבת - הספארי

אני יודע שלא כך עובדים היום אלא ב Database אבל רק לצורך הדוגמא ניקח את הספארי.
בספארי יש הרבה חיות אז כנראה תהיה מחלקת בסיס בשם Animal.
יש הרבה משפחות חיות קופים, פילים, ג'ירפות, נמרים וכו'.
לחלק מהמשפחות יש גם גזעים כמו לקופים: קוף אדם, גבון ועוד לחלק אין נניח ג'ירפות יש רק גזע אחד שהוא גם המשפחה. כלומר יהיו מחלקות שהן משפחות ויש להן רמה שלישית ויהיו מחלקות מהן יוצרים אוביקטים.
זו דוגמא פשוטה ביותר כי יש בפועל יש היררכיה הרבה יותר מורכבת.
לכל אוביקט רוצים גם לדעת מהו הסוג שלו (בפועל יש דרישה שבמחלקת הבסיס יהיה משתנה בשם type והוא גם נמצא בבנאי).
כעת לבעיות:
1. איך יוצרים אוביקט מהמחלקה הנכונה כאשר נוספת חיה חדשה נניח גירפה או גבון. (האם מיישמים FDP או שיש דרך אחרת?)
2. אם מיישמים FDP איך בוחרים מחלקה האם ב IF או SWITCH או שבכלל יש דרך טובה יותר?
3. בכל מחלקה יש בנאי. כאשר יוצרים אוביקט יש לנו type ואותו ניתן להעביר לבנאי של מחלקת הבסיס. במחלקות הביניים אין type אז איך מפעילים את הבנאי של הבסיס בלי type?
4. נניח יש חיה חדשה שלא כתבנו עבורה מחלקה. האם ניתן ליצור מחלקה ב Runtime או צריך לשנות את התוכנית?

תודה
 

selalerer

New member
למיטב הבנתי הבעיה שלך היא שאתה מתייחס למשפחה כחלק מההירכיה

אני חושב שמשפחה היא היררכיה נפרדת.
כלומר יש interface או base class בשם Family, ממנו יורשים משפחות שונות.
&nbsp
בהיררכיה של החיות, במחלקת הבסיס, יכולה להיות תכונה מסוג Family שהיא המשפחה של החיה ואת התכונה מאכלס למשל ה-constructor של החיה
 

tberger

New member
חלקית

1. לגבי יצירת האוביקטים הבנתי שמשתמשים במחלקה שמממשת את Factory design pattern. רק עוד לא סגור על המימוש עצמו. בעיקר מפריע לי השימוש בהרבה IF או switch כאשר שם המחלקה ידוע (מתקבל מהמשתמש או מה GUI) והפקודה ליצירת האובייקט זהה חוץ משם המחלקה.
2. עדיין אין לי פתרון לגבי ה Constructor של מחלקות ביניים. במחלקת הבסיס יש משתנה type (זו דרישה וכנראה שיש לזה שימוש למשל אם רוצים את כל העיגולים שיש) כאשר רק למחלקות שמהן יוצרים אוביקטים יש למעשה type ולמחלקות הביניים שהן אבסטרקטיות אין סוג אבל כדי להפעיל את הבנאי של מחלקת הבסיס צריך גם type.

תודה
 

BravoMan

Active member
אוי וואי...

אני חושב שיש בעיה בדרישות, או שלא הבנת את הדרישות, או שזה תרגיל קצת מכוער.
&nbsp
כך או כך, להלן כמה תשובות:
&nbsp
1. תשתמש ב-case לשם כך הוא נועד.
אין שום דרך אחרת, שכן לא רק שם המחלקה אצלך משתנה, אלא גם כמות וסוג פרמטרים לבנאי שלה.
&nbsp
2. קיבלת הוראה לקבל פרמטר type בבנאי של מחלקה "סופית".
היררכית מחלקות לא רלוונטית לעניין הזה.
תדאג שבמחלקת בסיס יהיה איבר type שהוא protected, כלומר, זמין רק ליורשים (לא משנה מאיזו דרגה, דרגות ירושה בד"כ לא רלוונטיות לכלום).
תן ערך לאיבר הזה בבנאי של מחלקה סופית. זה הכל.
 

tberger

New member
יצירת אוביקטים

תודה רבה על התשובה המפורטת.
מחיפוש הבנתי שעדיף להשתמש ב method factory במחלקת הבסיס.
הבנתי שיש גם אפשרות להשתמש ב map אבדוק זאת.
מעניין שלא נתנו אפשרות למשהו כמו template ב runtime כי מדובר בפקודה זהה שכל מה ששונה הוא שם ה class.
 
למעלה