11- templates

‫תכנות מכוון עצמים ו‪++C -‬‬
‫יחידה ‪11‬‬
‫תבניות ‪templates -‬‬
‫קרן כליף‬
‫ביחידה זו נלמד‪:‬‬
‫‪ ‬מוטיבציה לעבודה עם ‪templates‬‬
‫‪ ‬פונקציות ‪template‬‬
‫‪ ‬מחלקות ‪template‬‬
‫‪2‬‬
‫‪© Keren Kalif‬‬
‫מוטיבציה לשימוש ב‪template -‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪3‬‬
‫לפעמים יש פונקציות שעושות את אותה פעולה רק על טיפוסים‬
‫שונים‬
‫דוגמאות‪ find, bubleSort, max ,swap :‬וכד'‬
‫כיום עלינו להעמיס את הפונקציה כך שכל פעם תקבל את‬
‫הטיפוסים השונים‬
‫בשפת ‪ C‬פתרנו זאת באמצעות *‪void‬‬
‫בשפת ‪ ++C‬נפתור זאת באמצעות ‪ :template‬כתיבת פונקציה‬
‫כללית ללא ציון טיפוס ספציפי‬
‫‪© Keren Kalif‬‬
‫פונקצית ה‪swap :template -‬‬
‫עבור כל פונקצית ‪template‬‬
‫נזהה מהן הדרישות מהטיפוס‬
‫האם הפונקציה תעבוד‬
‫עבור מחרוזות?‬
‫הגדרה שהפונקציה היא תבנית ומתן‬
‫שם לטיפוס שאיתו עובדת הפונקציה‬
‫הפונקציה משתמשת באופרטור=‬
‫וב‪ copy c’tor -‬של האובייקט‬
‫‪4‬‬
‫‪© Keren Kalif‬‬
‫שליחת הפרמטר לפונקצית ‪template‬‬
‫פונקציה כללית להחזרת‬
‫סכום שני ערכים‬
‫הקומפיילר יודע לזהות ששני הפרמטרים הם‬
‫‪ int‬ולכן יודע להסיק שה‪ T -‬הוא ‪int‬‬
‫במקרה זה הקומפיילר לא יכול‬
‫לקבוע באופן חד משמעי מה‬
‫יהיה ה‪ int :T -‬או ‪double‬‬
‫‪5‬‬
‫‪© Keren Kalif‬‬
‫שליחת הפרמטר לפונקצית ‪)2( template‬‬
‫הפתרון‪ :‬במקרה של ‪ ambiguity‬יש לשלוח‬
‫בתוך < > את הטיפוס ‪ T‬באופן מפורש‬
‫‪6‬‬
‫‪© Keren Kalif‬‬
‫פונקציה המדפיסה את כל איברי המערך‬
‫שימוש‬
‫באופרטור ()‬
‫דרישה שלטיפוס ‪T‬‬
‫יהיה אופרטור >>‬
‫תזכורת‪ :‬אופרטור ()‬
‫‪7‬‬
‫‪© Keren Kalif‬‬
‫ההגבלות על המחלקה‬
‫‪ ‬במידה ובדוגמא הקודמת לא היה ממומש האופרטור >> עבור‬
‫המחלקה ‪ Point‬הייתה מתקבלת שגיאת הקומפילציה הבאה‪:‬‬
‫‪8‬‬
‫‪© Keren Kalif‬‬
‫דוגמא נוספת להגבלות על המחלקה‬
‫‪ ‬בדוגמא זו ההגבלות על הטיפוס ‪ T‬הן‪:‬‬
‫‪ ‬שתהייה עבורו השיטה ‪ getArea‬שתחזיר משתנה מטיפוס שניתן‬
‫לבצע עליו >>‬
‫‪ ‬שתהייה עבורו השיטה ‪ getPerimiter‬שתחזיר משתנה מטיפוס‬
‫שניתן לבצע עליו >>‬
‫‪9‬‬
‫‪© Keren Kalif‬‬
‫הארות‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪10‬‬
‫תמיד נתעד מהן הדרישות או ההגבלות על הטיפוסים שהם‬
‫הפרמטר לפונקציה‬
‫ניתן להגדיר פונקציית ‪ template‬עם יותר מטיפוס אחד‪:‬‬
‫>‪template<class T, class S‬‬
‫פונקצית ‪ template‬אינן פונקציה אחת‪ ,‬אלא אוסף של פונקציות‬
‫בעלות שם זהה‪ ,‬המבצעות את אותן פעולות‪ ,‬על טיפוסים שונים‬
‫עבור כל קריאה לפונקצית ‪ ,template‬הקומפיילר מייצר גירסא של‬
‫הפונקציה עבור הטיפוס המבוקש (ניפוח ה‪)exe -‬‬
‫‪© Keren Kalif‬‬
‫שימוש ב‪ template -‬לעומת פולימורפיזם‬
‫‪ ‬בדוגמא הקודמת ראינו אלגוריתם כללי להדפסת נתוני צורה‬
‫‪ ‬ניתן היה לבצע זאת גם באמצעות פולימורפיזם בעזרת שיטות‬
‫וירטואליות‬
‫‪template‬‬
‫פולימורפיזם‬
‫נפח הקוד‬
‫גדול‪ ,‬מאחר ויש שכפול עבור כל טיפוס‬
‫קטן‪ ,‬מאחר והאלגוריתם נמצא בבסיס‬
‫פעם אחת בלבד‬
‫זמן ריצה‬
‫הקישור מתבצע בזמן קומפילציה‪ ,‬לכן‬
‫טיפה יותר מהיר‬
‫הקישור דינאמי‪ ,‬ולכן טיפה יותר איטי‬
‫‪11‬‬
‫‪© Keren Kalif‬‬
‫מחלקת ‪template‬‬
‫‪ ‬ניתן להרחיב את השימוש ב‪ template -‬גם עבור מחלקות‬
‫שלמות‬
‫‪ ‬דוגמאות‪:‬‬
‫‪ ‬המחלקה ‪ Array‬שיודעת להחזיק נתוני מערך‪ .‬אין הבדל בתפעול בין‬
‫מערך של מספרים‪ ,‬תווים או נקודות‬
‫‪ ‬המחלקה ‪ List‬שיודעת להחזיק נתוני רשימה מקושרת‪ .‬פעולות‬
‫ההכנסה‪ ,‬הוצאה וכו' זהות עבור כל טיפוס‬
‫‪ ‬בהמשך תראו שיש את ה‪Standard Template ( STL -‬‬
‫‪ )Library‬אשר מממשת מבני‪-‬נתונים אלו בעזרת ‪template‬‬
‫‪12‬‬
‫‪© Keren Kalif‬‬
Array ‫ המחלקה‬:‫דוגמא‬
© Keren Kalif
13
‫דוגמא‪ :‬המחלקה ‪)2( Array‬‬
‫כל הפונקציות ממומשות ב‪-‬‬
‫‪ h‬מתחת למחלקה‪ ,‬מאחר‬
‫והקומפיילר צריך שהקוד‬
‫יהיה נגיש בזמן קומפילציה‬
‫כאשר מממשים את הפונקציות‬
‫מתחת למחלקה יש לציין שוב‬
‫שזוהי פונקציית ‪template‬‬
‫שם המחלקה המלא‬
‫הוא עם הטיפוס‬
‫‪14‬‬
‫‪© Keren Kalif‬‬
)3( Array ‫ המחלקה‬:‫דוגמא‬
© Keren Kalif
15
Array ‫שימוש במחלקה‬
© Keren Kalif
16
)2( Array ‫שימוש במחלקה‬
© Keren Kalif
17
‫פרמטר הטיפוס יכול להיות מורכב‬
‫כאשר הפרמטר הוא טיפוס ‪ ,temaplte‬יש‬
‫קומפיילרים שצריכים את הרווח בין ‪ 2‬ה‪<< -‬‬
‫‪ matArr‬מכיל ‪ 3‬איברים ש‪'\n' -‬‬
‫מפריד בינהם בהדפסה‪ ,‬וכל‬
‫איבר בהם הוא מערך של ‪int 10‬‬
‫‪9‬‬
‫‪2‬‬
‫‪5‬‬
‫‪3‬‬
‫‪4‬‬
‫‪2‬‬
‫‪5‬‬
‫‪ intArr1‬מכיל ‪ 5‬איברים ש‪' ' -‬‬
‫מפריד בינהם בהדפסה‬
‫‪9‬‬
‫‪2‬‬
‫‪5‬‬
‫‪ intArr2‬מכיל ‪ 2‬איברים ש‪' ' -‬‬
‫מפריד בינהם בהדפסה‬
‫‪18‬‬
‫‪© Keren Kalif‬‬
‫‪3‬‬
‫‪4‬‬
‫דוגמא מורכבת (‪)1‬‬
‫כיצד ישתנה הפלט אם לא‬
‫יהיה ‪ virtual d’tor‬ב‪?Base -‬‬
‫‪19‬‬
‫‪© Keren Kalif‬‬
)2( ‫דוגמא מורכבת‬
b (Base<Derived<int>>)  val (Derived<int>)  val (int)
© Keren Kalif
20
)3( ‫דוגמא מורכבת‬
bd (Derived<Base<int>>)  val (Base<int>)  val (int)
© Keren Kalif
21
‫דוגמא למחלקה המקבלת ‪ 2‬טיפוסים‬
‫‪22‬‬
‫‪© Keren Kalif‬‬
‫האם יתקמפל?‬
‫אם כן מה הפלט‪ ,‬אחרת מהי השגיאה?‬
‫לא יתקמפל מאחר יש דרישה‬
‫של‪ Tem -‬יהיה ‪default c’tor‬‬
‫‪23‬‬
‫‪© Keren Kalif‬‬
‫האם יתקמפל?‬
‫אם כן מה הפלט‪ ,‬אחרת מהי השגיאה?‬
‫)‪t1 (Tem<Tem<A>>)  t (Tem<A>)  t (A‬‬
‫נשים לב שזה לא‬
‫‪!copy c’tor‬‬
‫‪24‬‬
‫‪© Keren Kalif‬‬
‫האם יתקמפל?‬
‫אם כן מה הפלט‪ ,‬אחרת מהי השגיאה?‬
‫לא יתקמפל כי הקומפיילר‬
‫לא ידע להסיק מהו ‪S‬‬
‫לא יתקמפל כי הקומפיילר‬
‫לא ידע להסיק מהו ‪:S‬‬
‫‪ double‬או ‪int‬‬
‫‪25‬‬
‫‪© Keren Kalif‬‬
‫האם יתקמפל?‬
‫אם כן מה הפלט‪ ,‬אחרת מהי השגיאה?‬
‫לא יתקמפל כי ל‪Double -‬‬
‫אין בנאי המקבל ‪int‬‬
‫‪26‬‬
‫‪© Keren Kalif‬‬
‫ביחידה זו למדנו‪:‬‬
‫‪ ‬מוטיבציה לעבודה עם ‪templates‬‬
‫‪ ‬פונקציות ‪template‬‬
‫‪ ‬מחלקות ‪template‬‬
‫‪27‬‬
‫‪© Keren Kalif‬‬