מערך דינמי בC++

tseliot

New member
מערך דינמי בC++

אני מעוניין ליצור מחלקה שמתארת מערך דינמי של אובייקטים- כלומר, כשהיא נוצרת המערך שהיא מכילה הוא בגודל אפס, וכל פעם שפונים לפונקציה Add(object O) המערך גדל ב-1 והאובייקט נוסף במקום החדש. אני יודע איך לעשות את זה בC#:
public class MyArray { private object[] theArray; public MyArray(){theArray=new Object[0]} public void Add(object O) { object[] Temp=new Object[theArray.length+1]; for(int i=0;i<=theArray.length-1;i++) { Temp=theArray; } Temp[Temp.length-1]=O; theArray=Temp; } }

איך ניתן לתרגם את הפתרון לC++? נ.ב. אני לא רוצה להשתמש בTemplates. תודה רבה
 

vinney

Well-known member
אם לא היית מוסיף את הנ"ב

הייתי אומר "יש לך מוכן בספריה סטנדרטית, קוראים לזה VECTOR" מכיוון שאתה רוצה להמציא את הגלגל מחדש, אתה יכול לעשות אחד לאחד את מה שעשית, רק שבניגוד ל#C, אין לך מחלקה אחת (OBJECT) שממנה כולם יורשים, במקום זאת אתה יכול להשתמש ב *VOID והלקוח יצטרך לעשות CASTING. אבל כמובן שזה פתרון צולע, והפתרון הנכון ב++C זה הVECTOR ו/או שימוש בTEMPLATE.
 

tseliot

New member
הכוונה למערך דינמי למחלקה ספציפית

לדוגמא, אם יש לי מחלקה Apple, אז המחלקה שאני רוצה תהיה AppleArray. אחרת באמת הייתי משתמש בTemplates. בדוגמא שהבאתי של C#, השתמשתי בobject סתם למען הבהרה, אתה יכול להחליף את המילה Object בכל מה שתרצה שם (בהנחה שמחלקה עם שם כזה קיימת כמובן). אז- בהנחה שיש לי מחלקה Apple, ואני רוצה לעשות מערך דינמי של תפוחים- מה יהיה הקוד של מחלקה כזו?
 

vinney

Well-known member
זה כל הרעיון של TEMPLATE

להחליף את OBJECT בכל מה שתרצה זה בדיוק מה שTEMPLATE עושה. רק בניגוד ל#C שעושה את זה בזמן ריצה, TEMPLATE עושה את זה בזמן קומפילציה, וכך יוצר קוד הרבה יותר יעיל. שימוש בOBJECT ב#C דומה בהרסנותו לשימוש בRTTI ב++C, וצריך להזהר עם זה. ככלל, STL זה היישום היעיל ביותר למחלקות כלליות, ורק אם למחלקה שלך יש מאפיינים ממש ממש יחודיים, תוכל לעשות משהו ספציפי שיהיה יעיל יותר, כבר דננו בזה פה.
 

tseliot

New member
יש לכם טעות בסיסית בהבנת השאלה

תשכחו מהשימוש בממונח object- זו רק היתה דוגמה. מעולם לא אמרתי שאני מתכנן ליצור מערך של objects ואז לגזור ממנו כל מערך שארצה למשהו אחר. ניסוח מחדש:
public class Apple { //Some Code Here } public class AppleArray { private Apple[] theArray; public AppleArray() { theArray=new Apple[0]; } public void Add(Apple theApple) { Apple[] Temp=new Apple[theArray.Length+1]; for(int i=0;i<=theArray.Length-1;i++) { Temp=theArray; } Temp[Temp.Length-1]=theApple; theArray=Temp; } }

אוקי-איך אני מתרגם את הקוד הנ"ל לc++ בלי שימוש בTemplates? המטרה היא למען הבנה ולימוד, לא למען פרקטיות. אחרי שאני אבין איך עושים את זה לא תהיה לי בעיה להשתמש בTemplates. תודה
 

vinney

Well-known member
באותה צורה

אני לא מבין מה אתה מנסה ללמוד אבל זה תכנות לחלוטין לא נכון ולא לפי הכלים ש++C נותנת.
 

tseliot

New member
אני עדיין מרגיש שאני לא מובן...

אני אפשט את השאלה עוד יותר... יש לי מערך theArray בעל 5 איברים מסוג Apple. איך אני הופך אותו למערך בעל 6 איברים מסוג Apple, כאשר חמשת האיברים הראשונים הם אותם חמשה איברים והאיבר השישי הוא איבר חדש?
 

vinney

Well-known member
על realloc שמעת?

אם אתה משתמש ב NEW/DELETE ולא בכלים של C, אז אתה צריך להעתיק את כל המערך מחדש. עדיין, לא ברור לי למה אתה רוצה ללמוד לעשות משהו שהוא בעליל לא נכון. ב++C כשעובדים עם מחלקות, לא צריך לעשות מערכים, אלא להשתמש בSTLים, הרבה יותר נוח. גפ VECTOR נותן לך גישה אקראית לכל איבר במערך.
 

tseliot

New member
אוקי, אז מה הגישה הנכונה?

אני הייתי בטוח שTemplate בנוי כך שהוא עושה בדיוק מה שאני רציתי לעשות, ושאני פשוט בונה אותו שיתאים למחלקה שאני רוצה....
 

vinney

Well-known member
תסתכל על הVECTOR

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

tseliot

New member
לא! אסור לישון!

אין לי מושג מה זה Stl. אני למדתי את רוב מה שאני יודע מנסיון וטעיה. איפה אני מוצא את Vector?
 

DadleFish

New member
חבל מאוד שככה אתה לומד,

אתה רוכש לך הרגלים לא טובים. חפש את הספר ++Thinking in C של ברוס אקל (Bruce eckel), הוא ניתן להורדה חופשית מהאתר של ברוס, וזה הספר ל-++C.
 

tseliot

New member
לא להגזים...

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

tseliot

New member
וגם...

השורה:
theArray=new object[0];​
לא מתקבלת בC++- המהדר לא מאפשר ליצור מערך בגודל 0, וגם לא מסכים לקבל משתנה (Length) כגודל המערך החדש.
 

vinney

Well-known member
זה מצביע בודד

זה הבדלים בתחביר של השפות, לא הבדלים פונקציונליים מהותיים
 

ahab

New member
בנוסף..

זו גם לא הדרך המועדפת לעשות את זה ב-#C. כבר יש לך מחלקה בשם ArrayList שעושה את זה בשבילך. למה להמציא את הגלגל מחדש? ועוד בצורה לא יעילה - חבל להעתיק את כל המערך עבור כל הוספה.
 

tseliot

New member
אז זהו שלא...

בפורום דוט נט כבר הבהירו לי שלמעשה המחלקה ArrayList עושה בדיוק את אותה עבודה שאני כתבתי כאן כל פעם- היא פשוט לא מדווחת לך. מה גם שאני לא "מעתיק" את כל המערך מחדש, פשוט מעביר את הREFRENCE של כל איבר ממערך א למערך ב- זה רק "Handle" שעובר, לא כל האיבר...
 

itaym02

New member
למה לא רשימה מקושרת?

או שאתה רוצה שהמערך יעבוד גם על אובייקטים שלא אתה כתבת?
 

tseliot

New member
רוצה שמהערך יעבוד לאובייקט ספציפי

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