בתשובה לערן בילינסקי, 17/06/07 13:11
הנוער של ימינו 447448
אכן, אבל אתה חייב להודות שהקוד שם נראה מסורבל למדי... ולא ברור לי מה קורה כשעושים משהו מורכב יותר - למשל, כשרוצים לעשות משהו דמוי collect, שמחזיר את המערך שמתקבל אחרי שמפעילים פונקציה על כל אברי המקור, או find שמחזיר תת מערך של אברי המקור שמקיימים קריטריון מסויים, וכשמשלבים אותם יחד באותה שורה.
הנוער של ימינו 447544
כפי שכבר נאמר כאן, סיפלוספלוס היא מולטי-פאראדיגמטית וגם קצת מסובכת (יחסית לשפות תיכנות אחרות). יש לזה חסרונות ברורים: זמן הפיתוח קצת ארוך יותר, למתכנתים ולמעצבים פחות מנוסים קל יותר לשגות והקוד לפעמים עלול להיות קצת קשה יותר להבנה.

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

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

לשאלותך, עד כמה שהבנתי אותן, ב-STL נכללים לא-מעט אלגוריתמים שימושיים, וביניהם כאלה שעונים עליהן. יש פונקציות רבות לחיפוש מותנה כמו למשל find_if, search_n או search, ויש גם כמה אפשרויות להפעיל פונקציה על כל אברי קונטיינר, כמו for_each שכבר הוזכר קודם, ו-transform.

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

הגישה הכללית של ה-stl היא אכן להשתמש ב-functors, וזה לא תמיד נוח או אלגנטי. אבל יש אינסוף אלטרנטיביות, החל ממימוש אד-הוק (אין-ליין) של הפעולה הדרושה, דרך כתיבה של פונקציות, פונקציות-תבנתיות או מאקרו-יים לצורך הענייין וכלה בשימוש בספריות חיצוניות, שחלקן סטדנדרטיות מאד, כמו למשל ספריות ה-boost. לדוגמא:
הנוער של ימינו 447546
אני מסכים איתך כמעט לגבי הכל, פרט ל-Operator overloading. המנגון הזה בדרך כלל אינו אינטואיטיבי (בניגוד לאחרים, טוב, גם חישובי קיצין ומצביעים לא היו כוס התה שלי) ויש לו תועלת לדעתי רק במקרים מאוד ספציפיים - מחלקות מתמטיות, מצביעים חכמים ו-function objects. ספרטניות בשימוש במנגנון זה דווקא עדיפה בעיני.
הנוער של ימינו 447550
לא בהכרח. לא היית רוצה שתהיה לך, לדוגמה, אפשרות של חיסור מערכים? יש שתי משמעויות מוסכמות בלבד שאני יכול לחשוב עליהן לדבר הזה, ולא קשה לבחור אחת ולדבוק בה.
הנוער של ימינו 447551
כשאתה אומר "חיסור מערכים" אתה מתכוון לפעולות על מטריצות באופן כללי? אם כן, זה נופל אצלי תחת "מחלקות מתמטיות".
הנוער של ימינו 447555
לא, הכוונה היא ''תוציא מהמערך שבאגף שמאל את האיברים שיש במערך שבצד ימין''.
הנוער של ימינו 447557
אני מוכן להתפשר איתך גם על זה למערכים ו-collections (אבל מעדיף שמות משמעותיים כמו union, intersect וכו'). אבל לא הרבה מעבר לזה. לא רוצה ש-Employee יתווסף ל-Department על ידי האופרטור +, ויגרע ממנה על ידי האופרטור -.
הנוער של ימינו 447558
כן, זה כבר באמת נראה כמו הורדה לזנות.
הנוער של ימינו 447573
גם new ו-delete הם אופרטורים.
הנוער של ימינו 447548
אולי כדאי להעיר שוב שהדוגמה (הפשוטה) של for_each שהבאתי קודם באה בעיקר להציג עד כמה התחביר של רובי אלגנטי לעומת מה שקורה במקומות אחרים. שימוש ב-STL, לפחות השימוש שיצא לי לעשות, דורש קצת עבודת הכנה והוא אף פעם לא אלגנטי באותה המידה. זו לא תחרות של "מה השפה שלי יודעת לעשות ששלך לא" (אבל מה שכן, האם ב-++C יש יכולות אינטרוספקטיביות?)
הנוער של ימינו 447554
(למיטב זכרוני, רק בהרחבות שפה של Visual C++ של מייקרוסופט. בשפה עצמה אין אינטרוספקציה, ואין טעינה דינאמית כמו ב-Java).
הנוער של ימינו 447779
מה הן יכולות אינטרוספקטיביות?
הנוער של ימינו 447799
גישה לעצם המתאר את המחלקה. בדרך כללל זה נותן גישה לשם המחלקה, לעצמים המחזיקים את המתודות שלה וכו'. זה גם מאפשר לטעון באופן דינמי מחלקות בזמן ריצה (למשל, לקרוא שם של מחלקה מקובץ קונפיגורציה, למשל שימוש ב-Factory שונה לכל מערכת הפעלה, עבור מחלקות המימוש של הספריה הגרפית. ברגע שיש לנו את שם המחלקה, נשתמש בטוען מחלקות: ב-Java זהו ה-ClassLoader, כדי ליצור מופע חדש של עצם מהמחלקה הנ"ל), ואפילו להפעיל מתודות לא דרך הממשק הרגיל של

object.someMethod(arg1, arg2)

אלא על ידי שימוש במחלקה ש"מפעילה" את המתודה. למשל

invoker.invoke(object, methodName, argsArray)

ובטח יש עוד דברים שלא הזכרתי כאן.
הנוער של ימינו 447880
תודה.

חזרה לעמוד הראשי המאמר המלא

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