1 נושאי התרגול : Copy constructor Assignment operator המרת טיפוסים אוטומטיות. תכנות גנרי - Templates.

Slides:



Advertisements
Similar presentations
ממיבחניםC שאלות ++.
Advertisements

תוכנה 1 סמסטר א ' תשע " ב תרגול מס ' 7 * מנשקים, דיאגרמות וביטים * לא בהכרח בסדר הזה.
מבוא למדעי המחשב לתעשייה וניהול
האוניברסיטה העברית בירושלים
תרגול 8 היכרות עם ++C. C++ מעל שפת Cשפת תכנות שנבנתה מעל שפת C CC++ –כמעט כל תכנית ב -C היא גם תכנית ב C++ עד כדי מספר הבדלים קטן C99C שאימץ כמה מהתכונות.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב'
רקורסיות נושאי השיעור פתרון משוואות רקורסיביות שיטת ההצבה
תרגול 5 רקורסיות. רקורסיה קריאה של פונקציה לעצמה –באופן ישיר או באופן עקיף היתרון : תכנות של דברים מסובכים נעשה ברור ונוח יותר, מכיוון שזו למעשה צורת.
מבוא לשפת C חידות ונקודות חשובות נכתב על-ידי יורי פקלני. © כל הזכויות שמורות לטכניון – מכון טכנולוגי לישראל.
1 Formal Specifications for Complex Systems (236368) Tutorial #5 Refinement in Z: data refinement; operations refinement; their combinations.
מבוא למדעי המחשב © אריק פרידמן 1 מצביעים כמערכים דוגמה.
תרגול חזרה. מבנה האובייקט תאר את מבנה האובייקט כולל מבנה טבלאות הפונקציות הוירטואליות עבור התכנית הבאה struct A { int x; virtual void a() {}; }; struct.
1 ++C: יוצרים, הורסים ואופרטורים. 2 המחלקה Stack תזכורת class Stack { private: int* array; int size, top_index; public: Result init (int size) ; void.
Formal Specifications for Complex Systems (236368) Tutorial #6 appendix Statecharts vs. Raphsody 7 (theory vs. practice)
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
1 Formal Specifications for Complex Systems (236368) Tutorial #1 Course site : T.A. :Emilia Katz.
ערכים עצמיים בשיטות נומריות. משוואה אופינית X מציין וקטור עצמי מציינת ערך עצמי תואם לוקטור.
תרגול 10: הכרות עם ++C ++C כ- C משופר
1 נושאי התרגול : תכנות גנרי - Templates ירושה ופולימורפיזם.
אלכסנדר ברנגולץ דואר אלקטרוני: אלכסנדר ברנגולץ דואר אלקטרוני: פעולות מורפולוגיות.
1 ++C: יוצרים, הורסים ואופרטורים. 2 המחלקה Stack תזכורת class Stack { private: int* array; int size, top_index; public: Result init (int size) ; void.
C++: יוצרים, הורסים ואופרטורים. המחלקה Stack - תזכורת class Stack { private: int* array; int size; int topIndex; public: Result init (int size); void.
מערכים עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר int grade1, grade2, …, grade20; int grade1, grade2, …, grade20;
עקרון ההכלה וההדחה.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב' Templates תבניות.
מבוא למדעי המחשב תרגול 3 שעת קבלה : יום שני 11:00-12:00 דוא " ל :
1 נושאי התרגול : Copy constructorCopy constructor Assignment operatorAssignment operator המרת טיפוסים אוטומטיות המרת טיפוסים אוטומטיות תכנות גנרי – Templates.
© המרכז להוראת המדעים האוניברסיטה העברית בירושלים
מתמטיקה בדידה תרגול 2.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
אתחול עצמים. אתחולים ובנאים יצירת מופע חדש של עצם כוללת: הקצאת זכרון, אתחול, הפעלת בנאים והשמה לשדות במסגרת ריצת הבנאי נקראים גם הבנאי/ם של מחלקת הבסיס.
המשך תכנות מונחה עצמים 1. היום בתרגול  הורשה  שיטות מיוחדות  פולימורפיזם 2.
הגדרת משתנים יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר.
פיתוח מערכות מידע Class diagrams Aggregation, Composition and Generalization.
Methods public class Demonstrate { public static void main (String argv[]) { public static void main (String argv[]) { int script = 6, acting = 9, directing.
Practice session 3 תחביר ממשי ( קונקרטי ) ותחביר מופשט ( אבסטרקטי ) שיטות חישוב : Applicative & Normal Evaluation Partial Evaluation.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 7. סברוטינות subroutines.
Practice session 3.  תחביר ממשי ( קונקרטי ) ותחביר מופשט ( אבסטרקטי )  שיטות חישוב : Applicative & Normal Evaluation.
 Client, Supplier ומה שביניהם ( ADT!).  שאלה 1: יצירת ADT עבור מעגל במישור נניח שלקוח מעוניין בפעולות הבאות : הזזת מעגל וחישוב שטח מעגל. הספק יספק ללקוח.
תכנות מכוון עצמים ושפת ++C וויסאם חלילי. TODAY TOPICS: 1. Function Overloading & Default Parameters 2. Arguments By Reference 3. Multiple #include’s 4.
מבנים קרן כליף. ביחידה זו נלמד :  מהו מבנה (struct)  איתחול מבנה  השמת מבנים  השוואת מבנים  העברת מבנה לפונקציה  מבנה בתוך מבנה  מערך של מבנים.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 6. מפעל השעווה – לולאות  עד עכשיו  טיפלנו בייצור נרות מסוג אחד, במחיר אחיד  למדנו להתמודד עם טיפול במקרים שונים.
1 תרגול 11: Design Patterns ומחלקות פנימיות אסף זריצקי ומתי שמרת 1 תוכנה 1.
1 Formal Specifications for Complex Systems (236368) Tutorial #1 Course site:
מחרוזות – הטיפוס String
Object Oriented Programming
Object Oriented Programming
תכנות מכוון עצמים ו- C++ יחידה 11 תבניות - templates
Operators Overloading
Formal Specifications for Complex Systems (236368) Tutorial #1
Object Oriented Programming
Object Oriented Programming
מחלקות classes.
הורשה ופולימורפיזם צורה ריבוע משושה עיגול תרגול 13: ירושה
מבוא לתכנות מונחה עצמים Object Oriented Programming
מצביעים קרן כליף.
SQL בסיסי – הגדרה אינדוקטיבית
תכנות מכוון עצמים ושפת JAVA
Static and enum קרן כליף.
תכנות מכוון עצמים בשפת JAVA
ממשקים - interfaces איך לאפשר "הורשה מרובה".
ניתוח מערכות מידע תכנות ב C#
תכנות מכוון עצמים ושפת JAVA
סוגי משתנים קרן כליף.
מבוא לתכנות מונחה עצמים Object Oriented Programming
תוכנה 1 תרגול 13 – סיכום.
תכנות מכוון עצמים ו- C++ יחידה 02 העמסת פונקציות, ערכי ברירת מחדל, enum, קימפול מותנה קרן כליף.
תירגול 8:מצביעים והקצאה דינאמית
Computer Programming תרגול 3 Summer 2016
Engineering Programming A
Presentation transcript:

1 נושאי התרגול : Copy constructor Assignment operator המרת טיפוסים אוטומטיות. תכנות גנרי - Templates

2 Copy constructor & Assignment operator מה קורה כאשר מבצעים s1 = s2? מה קורה כאשר מבצעים Stack s1 = s2? מה ההבדל ? מה הסכנה ? מה קורה כאשר קוראים לפונקציה : f(Stack s) ; f(Stack& s) ; פתרון copy c’tor - לאתחול, assign. Op. - להשמה

3 Copy constructor & Assignment operator עבור כל מחלקה חדשה, מוגדרות באופן אוטומטי שתי פונקציות : copy constructor - זהו c’tor המשמש לאתחול של עצם אחד של המחלקה ע " י עצם אחר של אותה מחלקה. פונקציה זו גם משמשת לאתחל פרמטרים בקריאה לפונקציות, כלומר כאשר מעבירים פרמטר מסוג מחלקה מסוימת by value, ערכי השדות של הפרמטרים מאותחלים ע " י קריאה לפונקציה זאת ( כנ " ל לגבי החזרת ערכים ). ה - prototype של פונקציה זו עבור מחלקה X הוא : X(const X&) מובטח שלא נשנה את הפרמטר המועבר אי אפשר להגדיר copy constructor באמצעות copy constructor

4 Copy constructor & Assignment operator אופרטור ההשמה (=) - פונקציה זו משמשת להשמה של עצמים מהמחלקה זה לזה פרט לאתחול של עצם אחד של המחלקה ע " י עצם אחר של אותה מחלקה ( במקרה של אתחול ייקרא ה -copy c’tor, אפילו אם משתמשים בסימן = בביצוע האתחול ). בשני המקרים, בפונקצית ברירת המחדל ההעתקה היא איבר איבר. יש מקרים שבהם העתקה איבר איבר אינה טובה ( למשל, במקרה בו יש מצביעים כשדות במחלקה ). במקרים האלה, על המשתמש להגדיר פונקציות אלו מחדש ( דוגמא להגדרה מחדש של אופרטורים אלו נראה במחלקה Stack בהמשך )

5 Copy constructor & Assignment operator כלל אצבע : בכל מחלקה בה יש שדות שהם מצביעים, יש להגדיר מחדש : Copy Constructor Assignment Operator Destructor

6 The Final Stack class Stack { int* array; int top_index, size; public: Stack (int s = 100) ; Stack (const Stack&) ; Stack& operator=(const Stack&); ~Stack() ; Result push(int e); Result pop() ; Result top(int& e); void print() ; };

7 Copy constructor Stack::Stack(const Stack & st) { array = new int [st.size]; if (array == 0) error(“out of memory”); // assumes error exits size = st.size; top_index = st.top_index; for (int top = 0 ; top<st.top_index; top++) array[top] = st.array[top]; }

8 Assignment operator Stack& Stack::operator=(const Stack& st) { if (this == &st) return *this; if (st.size != size) { delete[] array; array = new int[size = st.size]; } for (int top = 0 ; top<st.top; top++) array[top] = st.array[top]; top_index = top; return *this ; } חמשת הצעדים : בדיקת הצבה עצמית שחרור משאבים הקצאת משאבים חדשים אתחול השדות החזרת this*

9 User Defined Type Conversions ב ++C קיימים שני סוגי המרות טיפוסים אוטומטיות : Conversion by constructor. Conversion by conversion operator.

10 Conversion by construction בעזרת c’tors של מחלקה T אפשר להמיר כל מחלקה אחרת או טיפוסים פנימיים של השפה כך שיהפכו לאיבר מסוג T. ההמרה מתבצעת ע ” י הגדרת Constructor המקבל ארגומנט יחיד, מהטיפוס הנ ” ל. T(class C); //converts from class C to T ההמרה תתבצע אוטומטית על ידי הקומפיילר. ההמרה מאפשרת לקרוא לפונקציות המצפות לקבל ארגומנט מטיפוס T עם ארגומנט מטיפוס C במקום. דוגמא : – במחלקה Complex : המרה מ -double ( עוד מעט ) – המרה מ -* const char למחלקה String ( תרגול קודם )

11 דוגמא - המחלקה Complex נניח כי רוצים להגדיר מחלקה של מספרים מרוכבים. היינו רוצים גם לאפשר את פעולות החשבון הרגילות בין מספרים מרוכבים ומספרים שלמים. דרך אחת לעשות את זה היא להגדיר את כל האפשרויות עבור כל אופרטור, בדומה לדוגמא הבאה : class complex { double re,im; public: complex (double r, double i) {re = r; im = i;} friend complex operator+(complex, complex); friend complex operator+(complex, double); friend complex operator+(double, complex); // Do the same for the rest of the operators… }; שיטה זו מייגעת ומלאה חזרות מיותרות. דרך נוספת לעשות את אותו הדבר היא להגדיר constructor ל - complex אשר מקבל פרמטר יחיד מטיפוס double. ההמרה מ double ל complex תתבצע אוטומטית באמצעות constructor זה.

12 דוגמא - המחלקה Complex class complex { //... complex(double r) {re = r; im = 0;} friend complex operator+(complex,complex); }; המהדר יבצע את ההמרה באופן אוטומטי. לדוגמא : main() { complex a; complex b; a=b+23; } מה שמתבצע זה : 1.23 מומר ל - complex ע " י ה - constructor. 2. מתבצע חיבור בין שני complex. 3.a מקבל את התוצאה ע " י אופרטור ההשמה המוגדר כברירת מחדל ע " י המהדר ( העתקה איבר איבר ).

13 Conversion by conversion operator בעזרת אופרטורים מיוחדים שמוגדרים במחלקה T אפשר להמיר את T לטיפוסים פנימיים של השפה או למחלקות אחרות שכבר הוגדרו. הדרך היחידה להגדיר המרה לטיפוסים פנימיים של השפה (למה?). המרה זו מבוצעת ע ” י הגדרת conversion operator ( מתודה של המחלקה T). operator C() ; // converts from T to C. דוגמא : class Price { int Shekel, agorot ; … public : …. operator double() { return shekel + agorot / ;} … }; אם ניתן רצוי להיעזר ב Conversion by constructor ( של C). שימו לב שלאופרטור אין ערך החזרה אבל השתמשנו ב -return בתוכו עם ערך החזרה... מנפלאות הסינטקס של C++ ( אז מה כן מחזירים ?).

14 בעיות עם המרות אוטומטיות class x { //... x(int); x(char*); … }; class y{ //... y(int); …. }; class z {//... z(x); …. }; x f(x); y f(y); z g(z); void k1() { f(1);// Illegal: ambiguous f(x(1)) or f(y(1)) f(x(1)); f(y(1)); g("asdf") ; // Illegal: g(z(x("asdf"))) not tried g(z("asdf")); // O.k.: x(char*) is carried out } פרט לכך קיימות שתי בעיות עם המרות : – מתבצעת רק המרה אחת – עלולה להיווצר דו משמעות (ambiguity)

15 המרות ואופרטורים כזכור operators הם בעצם פונקציות. לכן גם עבורם יכולה להתבצע המרה. לדוגמה, אופרטור החיבור במחלקה Complex יכול להיקרא : c2 = c1 + 5 ; אולם אם אופרטור מוגדר כ method לא תתבצע המרה על הארגומנט הראשון שלו. בגלל בעיה זו, עדיף בד " כ להגדיר אופרטור ע " י פונק ' חיצונית. כך, הטיפול בשני האופרנדים יהיה סימטרי. class complex {... public: complex(double r) {re = r; im = 0;} operator+(const complex&); friend operator-(const complex&, const complex&); }; main() { complex c2,c1; c1=2.0+c2;// Error: 2.0 will not be converted c2=2.0-c2;// O.k.: 2.0 will be converted }

16 תכנות גנרי - Templates משמש בעיקר כאשר בונים Containers - מחלקות אשר מכילות עצמים אחרים, אולם אין חשיבות לתכונותיו הייחודיות של אותו עצם : אותן פעולות מוגדרות על ה Container ללא קשר לעצם שבו. לדוגמא עבור מחסנית תמיד יוגדרו : –push –pop –top ללא חשיבות אם זו מחסנית של int, char או String.

17 דוגמת המחסנית int_stack.h: class int_stack { int top_index,size; int* array ; public: int_stack(int s) ; void pop() ; void push(int e); int top() ; int size(); }; char_stack.h: class char_stack { int top_index,size; char* array ; public: char_stack(int s) ; void pop() ; void push(char e); char top() ; int size(); }; String_stack.h: class string_stack { int top_index,size; String* array ; public: string_stack(int s) ; void pop() ; void push(String e); String top() ; int size(); };

18 דוגמת המחסנית int_stack.cc ( חלקי ): int_stack::int_stack (int s) { top_index = 0 ; size = s ; array = new int[s]; } int int_stack::top() { return array[top_index-1]; } string_stack.cc ( חלקי ): string_stack::string_stack (int s) { top_index = 0 ; size = s ; array = new String[s]; } String string_stack::top() { return array[top_index-1]; }

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

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

21 מחסנית גנרית stack.h: template class stack { int top_index,size; T* array ; public: stack(int s=100) ; void pop() ; void push(T e); T top() ; int size(); }; int_stack.h: class int_stack { int top_index,size; int* array ; public: int_stack(int s) ; void pop() ; void push(int e); int top() ; int size(); };

22 מחסנית גנרית stack.h ( חלקי ): template stack ::stack (int s) { top_index = 0 ; size = s ; array = new T[s]; } template T stack :: top() { return array[top_index-1]; } int_stack.cc ( חלקי ): int_stack::int_stack (int s) { top_index = 0 ; size = s ; array = new int[s]; } int int_stack::top() { return array[top_index-1]; }

23 שמוש במחסנית הגנרית int main() { stack si(100); stack sc(3); si.push(5); sc.push(“xxx”); sc.push(6); // error ! si.size(); sc.size(); } int main() { int_stack si(100); si.push(5); si.push(“xxx”); // error ! si.size(); }

24 Templates Templates הינם כלי מאוד שמושי לצורך הגדרת Containers. למרבה הצער המימוש של Templates ב ++C מזכיר macro חכם ולכן כל הקוד של ה Template נמצא ב header file. כפי שהוצג או כ inline function. ישנן לא רק מחלקות שהן גנריות אלא גם פונקציות גנריות.

25 פונקציות גנריות int major (int a, int b, int c ) { if (a == b || a == c) return a ; if (b == c) return b ; exit(1); } שימוש : int j = major (1,3,3); // ok? char c = major (‘w’,’w’,’w’);//ok? String s1 = major(s1,s2,s3); //ok ? int j = major (1,’a’,’a’); //ok ? template T major (T a,T b, T c ) { if (a == b || a == c) return a ; if (b == c) return b ; exit(1); } שימוש : int j = major (1,3,3); // ok ? char c= major (‘w’,’w’,’w’); //ok String s1 = major(s1,s2,s3); // ok? int j = major (1,’a’,’a’); //ok ?

26 Templates - advanced issues למרות ש ה Template לא “מתעניין” בתכונותיו המיוחדות של הטיפוס המועבר כפרמטר הוא יכול להניח הנחות לגבי קיומם של פונקציות או מתודות מסוימות בו. –אילו הנחות הניח major על T ? אילו stack ? ניתן להעביר כמה טיפוסים שונים בפרמטר: template class hashtable { bool find (const K &k, D &d) ; … };

27 פרמטרים ל Template ניתן להעביר ל Template פרמטר שאינו טיפוס. פרמטר יכול להיות מחרוזת, שם פונקציה או קבוע : template class Vector { T vec[Dim] ; … }; Vector v ; Vector v1; Vector v2; Vector v3 ; מה היתרון בכך שגודל ה buffer הנו חלק מהטיפוס ? ( רמז מה יקרה ב v=v3 ? )

28 Templates - advanced issues טיפוס שנוצר ע ” י template הינו טיפוס לכל דבר. אולם בדרך כלל כתיבת שמו המלא מסובכת לכן נעזרים בקיצור הבא : typedef stack stack_int ; אם נרצה להגדיר מחסנית של מחסניות אזי נגדיר את הטיפוס typedef stack stack_stack_int; ונעזר בו : stack_int s1(100); stack_stack_int s2(5); s2.push(s1); // in this case push should have better // accepted const T& instead of T...