1 / 50

Welcome to LABCPP

Welcome to LABCPP. Course Staff. Teacher: Moti Freiman Teaching Assistants: Ofir Pele Yoni Peleg. Communications. WWW: http://www.cs.huji.ac.il/~labcpp Email: Personal questions should be sent only to labcpp@cs Forums: News – must read

becka
Download Presentation

Welcome to LABCPP

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Welcome to LABCPP

  2. Course Staff Teacher: • Moti Freiman Teaching Assistants: • Ofir Pele • Yoni Peleg

  3. Communications • WWW:http://www.cs.huji.ac.il/~labcpp • Email: Personal questions should be sent only to labcpp@cs • Forums: • News – must read • Q & A – ask the staff about material and exercises. • Students - personal use.

  4. Course Objectives • Object Oriented Programming (C++) • Operator overloading (C++) • Templates (C++) • Standard Templates Library (STL) • Other modern programming techniques • Practice of programming: • Design • Testing & Debugging • Efficiency & Portability • Modularity

  5. Books • Bjarne Strousrtup"C++ Programming Language", 3rd edition, Addison-Wesley. • Stanley B. B. Lippman et al."The C++ Primer", 3rd edition, Addison-Wesley 1998.

  6. Course Grading • 4 programming exercises • Final exam • Final grade: 50% exercises and 50% exam. You must get a passing grade at both exercises and exam solely. Shortage in computers - don’t wait for the last minute.

  7. From C to C++

  8. C++ - OO extension of C • Classes & methods • OO design of classes • Generic programming • Template allow for code reuse • Stricter type system • Some run-time checks & memory control • לקראת סוף שנות ה-80 הבינו שיש הרבה מאוד יתרונות לסי, מבחינת היעילות וכדו', אבל יש לה חסרונות ביחס לשפות אחרות שהיו באותה התקופה, שהיו מונחות עצמים. הפתרון היה להרכיב שפה חדשה שמכילה את היתרונות של השפה סי, אבל מוסיפה אפשרות לתכנות מונחה עצמים (לא חובה, בניגוד לג'אבה) • הקומפיילר הראשוני היה מתרגם מסי++ לסי, ואז מקמפל כרגיל כדי ליצור קובץ ריצה. היום יש קומפיילר שמתרגם ישר מסי++ לשפת מכונה. • הקומפיילר מוסיפה בדיקת טיפוסים יותר קפדנית. • יש תוספת של בדיקות זמן ריצה, אבל לא משהו שייפגע ביעילות.

  9. First Program in C++ // This line defines standard I/O library #include <iostream> int main() { std::cout << "Hello class!\n"; return 0; } אינקלוד אנחנו מכירים – אנחנו רוצים להשתמש בפונקציות חיצוניות. כאן הקובץ הוא בשם שונה, כמו שאפשר לראות, וגם לא צריך להוסיף .h . הפונקצייה המרכזית היא main, זהה לחלוטין לקודמת ב c. Std::cout אובייקט cout ששייך לחבילה std, שקורא למתודה >> (האובייקט קיים בקובץ החיצוני), והוא מקבל כפרמטר את מה שאחרי ה >>).

  10. Compiling & Running… >g++ –Wall hello.cpp –o hello > hello Hello class! >

  11. I/O in C++ - basics #include <iostream> #include <cmath> אפשר היה להשתמש באותו הקובץ שהשתמשנו גם בסי, אבל הקובץ הזה מכיל את מה שאנחנו צריכים גם לסיפיפי int main() { std::cout << "enter coeffs of quad equation" << std::endl;עושה אנטר – רד שורה ומחק את הבאפר (הסבר מיד). מה ההבדל בין סלש אן, לזה? זמן התגובה של המסך ממש איטי ביחס לסיפיו, לכן מערכת ההפעלה מקצה בפר מתוכה היא קוראת ונותנת למסך כשהוא מסוגל לשדר את זה. לפעמים רוצים להכריח את התוכנית להדפיס באותו הרגע את מה שרוצים, וזה מה שהפונקצייה הזו עושה – היא יורדת שורה ומוחקת את הבאפר. אם רשמנו סלש אן, יכול להיות שמה שיקרה אחרי מה שקורה יקרה, ועדיין לא הייתה הדפסה למסך. זה עלול ליצור בעייה בדיבאג וכדו', כי לא נדע מאיזו שורה הייתה הבעייה. double a,b,c; std::cin >> a >> b >> c; יש פה שלוש קריאות נפרדות לפונקצייה <<, כל פעם לקבלת הערך של האות שאותה אנחנו מעבירים. לא צריך להגיד לה איזה סוג הערך המועבר, הוא יודע לבד. double discriminant = sqrt(b*b-4*a*c); std::cout << "z1 = " << (-b+discriminant)/(2*a) << std::endl << "z2 = " << (-b-discriminant)/(2*a) << std::endl;שרשור הדפסות. שוב, לא צריך להעביר איזה סוג האובייקט שאנחנו רוצים להעביר, הוא יודע לבד. }

  12. I/O in C++ - type checking #include <iostream> int main() { char buf[100]; int a; double b; std::cin >> buf >> a >> b; מנסים למנוע אם ניסינו להעביר לפונקציה קר, ונתנו לו דאבל. יש לסין(האובייקט אחרי ה-::) מתודה בשם פייל (יעני נכשל) – מחזירה אמת אם הערך שמועבר הוא לא מהטיפוס שנדרש.מה יקרה אם הראשון נכשל והשני תקין? זה קוד לא טוב, אבל בעקרון מה שיקרה זה שהוא יישאר על פייל (נכשל) ולא יעבור הלאה. if(std::cin.fail()) { std::cerr << "input problem\n"; return 1; } std::cout << "I got: "<< buf << ' ' << a << ' ' << b << std::endl; }

  13. More about I/O in C++ • Files i/o: http://www.cplusplus.com/doc/tutorial/files.html • General tips for i/o: http://www.augustcouncil.com/~tgibson/tutorial/iotips.html • I/O manipulation (precision, etc.) http://www.cplusplus.com/ref/iostream/iomanip/ http://www.cppreference.com/cppio/index.html

  14. strings in C++ #include <iostream> #include <string>זה לא סטרינג דוט אייץ' מסי!אם רוצים את זה של סי, אפשר להוסיף קובץ בשם סיסטרינג. חשוב לא להתבלבל בין השניים. int main() { std::string str; int a; double b; std::cin >> str >> a >> b;לא צריך גודל לא כלום if(std::cin.fail()) { std::cerr << "input problem\n"; return 1; } std::cout << "I got: "<< str << ' ' << a << ' ' << b << std::endl; } בשפת סי לא היו סטרינגים.היה מערך עם סלש אן בסוף. אם קולטים מערך של קארים, שמהווה סטרינג, (כמו בדוגמא הקודמת) יש לו סלש אן בסוף.

  15. strings in C++ More about string functions: http://www.cppreference.com/cppstring #include <iostream> #include <string> int main() { std::string str; int a; double b; std::cin >> str >> a >> b; if(std::cin.fail()) { std::cerr << "input problem\n"; return 1; } std::cout << "I got: "<< str << ' ' << a << ' ' << b << std::endl; }

  16. Boolean variables #include <iostream> int main() { int a = 5; bool isZero = (a == 0); יש משתנה בול עם בי גדולה, שהוא בוליאני של ווינדואוז ומיתרגם אוטומטית לאינט. if(!isZero && isZero==false && isZero!=true && !!! isZero && a ) // same conditions { std::cout << "a is not zero\n"; } }

  17. Function overloading - C #include <stdio.h> void foo() { printf ("foo()\n"); } void foo(int n) { printf ("foo(%d)\n", n); } int main() { foo(12); foo(); return 0; }

  18. Function overloading - C #include <stdio.h> void foo() { printf ("foo()\n"); } void foo(int n) { printf ("foo(%d)\n", n); } int main() { foo(12); foo(); return 0; } אין אוברלואוד בסי! מבחינת הקומפיילר שם של פונקצייה זו תעודת הזהות שלה.אבל: יש שדרוג בסיפיפי (עוד 2 שקפים)

  19. Function overloading - C // compilation output Error: Multiple definition of foo #include <stdio.h> void foo() { printf ("foo()\n"); } void foo(int n) { printf ("foo(%d)\n", n); } int main() { foo(12); foo(); return 0; }

  20. Function overloading – C++ // output foo(12) foo() #include <iostream> void foo() { std::cout << "foo()\n"; } void foo(int n) { std::cout << "foo(" << n << ")\n"; } int main() { foo(12); foo(); } בסי יש אוברלואוד, וככה מבדילים בין שתי הפונקציות.

  21. Classes

  22. Motivating Example Goal: • Graphics package • Handle drawing of different shapes • Maintain list of shapes

  23. Solution #1 struct shape { enum { RECTANGLE, CIRCLE, TRIANGLE } _type; double _x, _y; double _height, _width; }; void Draw( shape const* Shape ) { switch( Shape->type ) { case RECTANGLE: … case CIRCLE: …

  24. Solution #1 - Discussion Pros: • Simple, direct Cons: • Adding new shapes requires changing all procedures that deal with shape • קל לתכנת ולקמפל. • חסרונות: כשרוצים להוסיף אלמנט חדש למה שהוגדר, נצטרך לעבור על כל המתודות, לתקן את הסוויץ', לבדוק שאין בלאגן.בסה"כ לא נוח לעבודת המשך.

  25. Solution #2 Allow to implement shape specific code struct shape { double _x, _y; double _height, _width; void (*Draw)( shape const* ); }; void Draw( shape const* Shape ) { (*Shape->Draw)(Shape); } נשים בתוך שייפ מצביע לפונקצייה שיהווה סוג של ממבר אצלה. כאן כל קריאה לפונקציה דורשת גם מעבר לפויינטר וגם מעבר מהפויינטר לפונקציה – בסה"כ פי 2 פעולות. יותר אלגנטי, פחות יעיל.

  26. Solution #2 Pros: • Extendable • Drawing method of each shape encapsulated • Efficient Cons: • No checks can lead to errors: • עושים קאסטינג, אבל האם מותר? בדוגמא הזו יהיה ארור, כי לפונקציה דרואו בשייפ 1 מעבירים את שייפ 2. (*Shape1->Draw)(Shape2);

  27. Solution #3 – C++ classes • Language provides tools for objects • Ideas similar to Java • Many differences in details

  28. Simple Class Declaration (Counter.h file) #ifndef _Counter_h כדי שלא נצהיר בטעות פעמיים #define _Counter_h class Counter { public:ממש כמו ג'אבה Counter(); // Constructor void increment(); // A method int value(); // Another one private:ממש כמו ג'אבה איזה כיף! int _count; }; #endif // _Counter_h

  29. Using the class (app.cpp file) #include "Counter.h" #include "cstdio" int main() { Counter cnt; // Call to constructor! שמות משתנים באות קטנה, שמות אובייקט באות גדולה. עצם ההצהרה קוראת לקוסטרקטור. זה לא פויינטר, זה משתנה שיושב על המחסנית של הפונקציה. printf("Initial value = %d\n", cnt.value() ); cnt.increment(); printf("New value = %d\n", cnt.value() ); }

  30. Class Implementation (Counter.cpp file) Implementation:איך מגדירים את המחלקה עצמה? בקובץ האייץ' הגדרנו את האובייקט, אבל לא מימשנו את הפונקציות. • Functions declared in the class definition • Constructor like a function, but no return type Counter::Counter() { _count = 0; }

  31. Class Implementation void Counter::increment() { _count++; } int Counter::value() { return _count; }

  32. Class Basics: Public/Private • Declare which parts of the class are accessible outside the class class Foo { public: … // accessible from outside private: … // private };דיפולטיבי (בלי פאבליק ובלי פרייבט) מוגדר כפרייבט בלבד. זה כי במעבר מסי לסיפיפי היו צריכים לעשות שמה שהיה בסי יעבוד בסיפיפי, אבל בסטראקט הייתה בעייה כי המשתנים לא הוגדרו. לכן, הוגדר שאם יש דברים שלא הוגדרו, הם יהיו פרייבט. הערה: אפשר כמה פעמים לעשות בלוקים של פרייבט או פאבליק, וכל מה שיש בתוך הבלוק הוא לפי ההצהרה שלפני. חשוב: אין פורוורד דקלריישן (הצהרה מוקדמת של פונקציות כדי להכיר לפונקציות הבאות לפניה אותה) בסיפיפי, כי בכל מקרה חייבים להכיר את המחלקה והפונקציה.

  33. class MyClass { public: int a(); double _x; private: int b(); double _y; }; int main() { MyClass foo; // legal foo._x = 1.0; foo.a(); // illegal foo._y = 2.0; foo.b(); } Example(ממש כמו ג'אבה)

  34. class MyClass { public: int a(); double _x; private: int b(); double _y; }; int MyClass::a() { // legal _x = 1.0; // also legal _y = 2.0; b(); } אנו מנסים לממש את פונקציה איי מחוץ לאובייקט, אבל בגלל ההצהרה של ה:: אנחנו כן נמצאים בתוך הקוד של המחלקה, לכן אפשר. כמובן שזה אפשרי רק אם המחלקה עצמה איננה פרטית. צריך להיזהר, שלא יהיה מימוש כפול של אותה המחלקה בשני קבצי אייץ' חיצוניים שונים, כי אז זה עלול ליצור סתירה בשימוש חיצוני שיבוא אחר כך. מה עושים? מממשים בקובץ מסוג סיפיפי. Example (שונה מג'אבה)

  35. Class Basics: Constructors • Initialize the class object upon construction class MyClass { public: MyClass(); MyClass( int i ); MyClass( double x, double y ); … }; … MyClass a; // Calls MyClass b(5); // Calls MyClass c( 1.0, 0.0 ); // Calls 1 2 3 1 2 3

  36. Constructors class MyClass { public: MyClass(); // default cons. … }; … int main() { MyClass a; // default cons. is called …

  37. Constructors (2) class MyClass { public: … }; … int main() { MyClass a; // default cons. is called … הקונסטרקטור הדיפולטיבי לא חייב להיות ממומש, כי כשיצרנו סטראקט בסי, אף אחד לא הגדיר קונסטרקטור, אבל הוא עדיין נוצר, וחייבים שתהיינה התאמה. הקונסטרקטור הדיפולטיבי שאיננו מוגדר מאתחל את השדות לפי הערכים הדיפולטיביים.

  38. Constructors (3) class MyClass { public: MyClass(int x); // no default cons. … }; … int main() { MyClass a; // failed – no default cons. … ההיגיון אומר שאם הוספנו קונסטרקטור, אז הקונסטרקטור הדיפולטיבי של התוכנה איננו קיים.

  39. Destructors • Ensure propose “cleanup” when the object is destructed • Use for freeing memory, notifying related objects, etc.

  40. #include <cstdlib> class MyClass { public: MyClass();הקצאת מקום לאובייקט, האובייקט כולל רק מצביע. ~MyClass(); // destructor private: char* _mem; }; MyClass::MyClass() { _mem = (char*)malloc(1000); } MyClass::~MyClass() { free(_mem);ישנו זיכרון יחידי – מצביע, וצריך לשחרר רק אותו } int main() { MyClass a; if( … ) { MyClass b; … }bשחרור … }aשחרור Class Basics: Destructors

  41. Class – Example See IntList.h and IntList.cpp • C++ implementation of data structure from last class • Data members of IntList are protected • Usage is more natural … IntList L; L.pushFront(6) if( !L.isEmpty() ) x = L.popBack();

  42. Consider this code main() { IntList L; … } What is the difference? Compare to main() { IntList* L = (IntList*)malloc( sizeof(IntList)); … free(L) } נתבונן בשתי הדוגמאות – בשניהם מקצים רשימת אינטים. בצד שמאל הליסט יושב על הסטאק של מיין. גם האובייקטים של הרשימה מוכלים במחסנית. מצד ימין, לעומת זאת, במיין יש פויינטר בלבד לאוביקט שנמצא על הערימה. אבל הצהרת המאלוק לא קוראת לבנאים! אז איך גם נצהיר על מקום וגם נבנה את האובייקט? Classes & Memory allocation

  43. Classes & Memory allocation IntList* L = (IntList*)malloc(sizeof(IntList)); • Does not call constructor! • Internal data members are not initialized free(L); • Does not call destructor! • Internal data members are not freed

  44. new & delete Special operators: • IntList *L = new IntList;אפשר להעביר פרמטרים בסוגריים אם רוצים קונסטרקטור שהוא לא הדיפולטיבי. הקריאה הזו מקצה זיכרון על הערימה כמובן. אם היינו רוצים על הסטאק זה היה בדיוק כמו שעשינו לפני כ-3 שקופיות. • allocate memory • call constructor כלל ברזל: לא להשתמש במאלוק ובפרי. • delete L; • call destructor • free memory אם יש בעייה בהקצאת הזכרון הוא לאו דווקא יחזיר נאל. אפשר לרשום את הקוד הבא כדי לוודא שאכן יוחזר נאל: … = new <std::badalloc> …

  45. New new <type>; • Allocate an object of type <type> • Apply constructor to the new object • Return a pointer to the new object Can be used with any type: int *i = new int; char **p = new (char *);

  46. New & Constructors class MyClass { public: MyClass(); MyClass( int i ); MyClass( double x, double y ); … }; … MyClass* a; a = new MyClass; // Calls a = new MyClass(5); // Calls a = new MyClass( 1.0, 0.0 ); // Calls 1 2 3 1 2 3

  47. New & arrays To allocate arrays, use כיצד נקצה מערך של אובייקט מסוג רשימת אינטים? int n = 4; int *a = new int[10]; // array of 10 ints IntList *b = new IntList[n]; // array of n IntLists אי אפשר להשתמש בקונסטרקטור שאינו דיפולטיבי בהצהרה של אובייקטים במערך. לא חוקי: intList *arr = new intList[5](3) הערה: הקומפיילר ג'יסיסי מאפשר להקצות מערך בגודל שלא נקבע מראש, אבל בעיקרון זה גרוע כי זה לא אמור להיות אפשרי בסיפיפי. • Objects in allocated array must have an argument-less constructor!

  48. Allocate array of objects w/o def. cons. int n = 4; MyClass **arr = new MyClass *[n]; // array of n pointers to MyClass (no cons. is invoked) for (int i=0;i<n;i++) { arr[i] = new MyClass (i); // each pointer points to a MyClass object allocated on the heap, and the cons. is invoked. }

  49. Delete & array Special operation to delete arrays int *a = new int[10]; int *b = new int[10]; … delete [] a; // proper delete command delete b; // works, but may cause memory leak!למה זה יעבוד? כי בד"כ מערכת ההפעלה זוכרת את הנתונים שנשמרו בתוך בי. וולגריינד יעלה על זיכרון שאבד כי וולגריינד זה אחלה.

  50. Free an allocated array of pointers to objects on the heap int n = 4; for (int i=0;i<n;i++) { delete (arr[i]); // invoked the dest. of each MyClass object allocated on the heap, and free the memory. } delete [] arr; // free the memory allocated for the array of pointers. No dest. is invoked באופן כללי- כמספר הלולאות שהשתמשנו בהצהרה (ניו), מספר הצהרות הדליט.

More Related