1 / 25

תרגול מס' 13

תרגול מס' 13. שאלות ממבחנים - C++. שאלה 1. בשאלה זאת עליכם לסייע בכתיבת תוכנית לניהול צי רכב של חברת השכרה.

hagop
Download Presentation

תרגול מס' 13

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. תרגול מס' 13 שאלות ממבחנים - C++

  2. שאלה 1 • בשאלה זאת עליכם לסייע בכתיבת תוכנית לניהול צי רכב של חברת השכרה. • סעיף א' (10 נקודות): עליכם לכתוב 3 מחלקות (ממשקים ומימושים) עבור 3 סוגי מכוניות שהחברה משכירה: Sedan (מכונית פרטית), Truck (מסחרית), ו- AllTerrain (רכב שטח), כולן יורשות ממחלקת בסיס אבסטרקטית משותפת Car (שגם אותה יש לכתוב). דרישות: • לכל מכונית יש מספר רישוי ייחודי • לכל מכונית ניתן לדעת אם היא פנויה או בהשכרה אצל לקוח, וניתן לשנות מצב זה מבחוץ. • ניתן להשוות מכוניות לפי מספר הרישוי • כל אובייקט מכונית יוכל להכין מעצמו עותק, באמצעות פונקצית מחלקה Clone, גם אם טיפוס האובייקט ידוע רק בזמן ריצה (כלומר – פולימורפיזם). הפונקציה תחזיר את כתובת המכונית החדשה. מבוא לתכנות מערכות - 234122

  3. פתרון • classCar { • intserNum; • boolvacant; • public: • Car(intsn) : • serNum(sn), vacant(true) {} • virtual~Car() {} • booloperator==(constCar &car) const { • returnserNum == car.serNum; • } • voidRent() { vacant = false; } • voidReturn() { vacant = true; } • boolIsVacant() const{returnvacant; } • virtualCar* Clone() const = 0; • }; מבוא לתכנות מערכות - 234122

  4. פתרון • classSedan: publicCar{ • public: • Sedan(intnum) : Car(num) {} • virtualCar* Clone() const { returnnew Sedan(*this); } • }; • classTruck: publicCar{ • public: • Truck(intnum) : Car(num){} • virtualCar* Clone() const { returnnew Truck(*this); } • }; • classAllTerrain: publicCar{ • public: • AllTerrain(intnum) : Car(num){} • virtualCar* Clone() const { returnnewAllTerrain(*this); } • }; מבוא לתכנות מערכות - 234122

  5. שאלה 1 - המשך • סעיף ב' (10 נקודות): נתונה המחלקה Customer (לקוח) שהממשק שלה: classCustomer{ stringname; intid; constCar *pRentedCar; public: Customer(conststring& n, int i); voidRentCar(constCar& car); voidReturnCar(); }; • עליכם לכתוב ממשק למחלקה Branch (סניף של החברה). אין צורך לממש את המחלקה Customer. מבוא לתכנות מערכות - 234122

  6. שאלה 1 - המשך • דרישות: • כל סניף יחזיק מערך של כלי הרכב שברשותו. המערך יכלול כלי רכב מכל 3 הסוגים. מספר כלי הרכב המקסימלי בסניף נתון ע"י קבוע. • לכל סניף יש שם ומספר סידורי. • כל סניף יוכל: הנחיות נוספות: • עבור הדרישות הנ"ל, פרט לדרישה 1, אם כלי הרכב הנדון לא נמצא בסניף, יש להתריע על כישלון הפעולה. • אם לא ניתן להוסיף מכונית מפאת חוסר מקום, הפונקציה המתאימה צריכה להתריע על כישלון הפעולה. • עבור כל אחת מהדרישות, הפונקציה המתאימה צריכה להיות יחידה, כלומר, אמורה לטפל בכל שלושת טיפוסי כלי הרכב • כל הדרישות הנ"ל ימומשו ע"י פונקציות מחלקה. • לבדוק אם כלי רכב נתון פנוי. אם כלי הרכב לא ברשימה, זה ייחשב כאילו הוא אינו פנוי. • לקבל כלי רכב חדש - הפונקציה המתאימה תיצור עותק של כלי הרכב • להוציא כלי רכב מהמלאי • להעביר כלי רכב לסניף אחר • לקבל כלי רכב מסניף אחר • להשכיר כלי רכב ללקוח • להחזיר כלי רכב מלקוח • ניתן לבנות סניף חדש בעזרת שם הסניף ומספרו מבוא לתכנות מערכות - 234122

  7. פתרון • classBranch { • staticconstintMAX_CARS = 100; • Car* cars[MAX_CARS]; • stringname; • intnumber; • public: // functionality • Branch(stringname,int number); // 8 • ~Branch(); • boolisCarVacant(constCar& car) const; // 1 • voidaddCar(constCar& car); // 2 • voidremoveCar(constCar& car); // 3 • voidtransferTo(Branch& branch, constCar& car); // 4 • voidtransferFrom(Branch& branch, constCar& car); // 5 • voidrentCar(Customer& customer, Car& car); // 6 • voidreturnCar(Customer& customer, Car& car); // 7 • }; • classBranchException : publicexception {}; מבוא לתכנות מערכות - 234122

  8. שאלה 1 - המשך • סעיף ג' (20 נקודות): יש לממש את הפונקציות האחראיות לפעולות 2) , 4), 5), 6), ו 8) • הנחיות: • יתכן צורך להגדיר משתני עזר ו/או פונקציות עזר נוספות במחלקות השונות. אם מגדירים פונקצית עזר, אין צורך לממש אותה, אלא רק לכתוב אב-טיפוס ולהסביר מה היא עושה. • אין להגדיר פונקציות או משתני מחלקה שלא מתחייבים מהדרישות, או מהנחייה 1) • אין להשתמש במבנים מ STL (פרט, אולי, ל-string) מבוא לתכנות מערכות - 234122

  9. הוספת פונקציות עזר וחריגות נוסיף למחלקה שתי פונקציות עזר ואת הגדרת החריגות המדויקות שנזדקק להן במימוש • class Branch { • staticconstintMAX_CARS = 100; • Car* cars[MAX_CARS]; • stringname; • intnumber; • intfindCarIndex(constCar& car); • boolcontains(constCar& car); • intfindEmptySlot(); • //... • }; • classCarAlreadyInBranch: publicBranchException {}; • classCarNotFound: publicBranchException {}; • classBranchFull: publicBranchException {}; • classCarNotRented: publicBranchException {}; • classCarAlreadyRented: publicBranchException {}; מבוא לתכנות מערכות - 234122

  10. מימוש פונקציות העזר בזכות השימוש בחריגות בפונקציות העזר פונקציות הקוראות להן לא יצטרכו לבדוק את ערך החזרה עבור מקרי קצה • intBranch::findCarIndex(constCar& car) { • for (int i = 0; i < MAX_CARS; i++) { • if (cars[i] && *cars[i] == car) { • return i;}}throwCarNotFound()}boolBranch::contains(constCar& car) { • try { • findCarIndex(car); • returntrue; • } catch (CarNotFound&) { • returnfalse;}}intBranch::findEmptySlot() { • for (int i = 0; i < MAX_CARS; i++) { • if (!cars[i]) { • return i;}}throwBranchFull();} נחסך הצורך בשימוש בערכי מספרים מיוחדים עבור מצביע השגיאה מבוא לתכנות מערכות - 234122

  11. פתרון 8) ניתן לבנות סניף חדש בעזרת שם הסניף ומספרו • Branch::Branch(string name, int number) • : name(name), number(number) { • for (int i=0; i<MAX_CARS; i++) { • cars[i] = NULL; • } • } • voidBranch::addCar(constCar& car) { • if (contains(car)){ • throwCarAlreadyInBranch(); • } • int index = findEmptySlot(); • cars[index] = car.Clone(); • return; • } 2) לקבל כלי רכב חדש - הפונקציה המתאימה תיצור עותק של כלי הרכב מבוא לתכנות מערכות - 234122

  12. פתרון • voidBranch::transferTo(Branch& branch, constCar& car) { • removeCar(car); • branch.addCar(car); • } • voidBranch::transferFrom(Branch& branch, constCar& car) { • branch.transferTo(*this, car); • } • voidBranch::rentCar(Customer& customer, Car& car) { • int index = findCarIndex(car); • if (!isCarVacant(car)) { • throwCarAlreadyRented(); • } • cars[index]->Rent(); • customer.RentCar(car); • } 4) להעביר כלי רכב לסניף אחר 5) לקבל כלי רכב מסניף אחר 6) להשכיר כלי רכב ללקוח מבוא לתכנות מערכות - 234122

  13. שאלה 2 • עליכם לממש מחלקות גנריות עבור "מערכים בטוחים". מערך בטוח הוא מערך המכיל מידע על אורכו, המאפשר הגנה מפני גלישה בשימוש. הגנריות מתבטאת בעובדה שהמימוש מאפשר ליצור מערכים שונים עבור סוגי עצמים שונים. למשל, הפקודה • array<double> vec(12) • תיצור מערך של double בגודל 12. כדי למנוע שכפול קוד ע"י הקומפיילר (לכל instance של ה-template), יש לאסוף את החלקים המשותפים במחלקת בסיס class arrayBase ואח"כ לבצע הורשה: • template <class T> class array: public arrayBase {...} • יש לממש מחלקות כדי שהתוכנית למטה תתבצע כפי שנדרש. שימו לב: בראש הקוד הושמטו שמות המחלקות; עליכם להשלים את הקוד. מומלץ לקרוא את כל הקוד לפני פתרון השאלה. • סעיף א (15 נקודות): הגדרת המחלקות: • הגדירו את המחלקות 1T, 2T, 3T, ו-T4 עם מתודות סבירות לשימוש קל ונוח במערכים (כולל קלט/פלט). שימו לב כי יש להגדיר את כל שדות הנתונים ולהצהיר על כל הפונקציות הנדרשות. אין צורך לממש שום פונקציה. הגדירו גם את המחלקה לטיפול בחריגות. • סעיף ב (20 נקודות): מימוש (חלק מהפונקציות של) המחלקות: • ממשו את הפונקציות הבאות בכל מחלקה בה הן מופיעות: בנאים (constructors) אין צורך לאפס ערכים לא מאותחלים, הורסים (destructors), אופרטור פלט (operator<<), ופעולת אינדקס (operator[]), טפלו נכון בשגיאות. מבוא לתכנות מערכות - 234122

  14. קוד השימוש במחלקות • typedef ........ T1; • typedef ........ T2; • typedef ........ T3; • typedef........ T4; • //... more code? ... • intmain () { • try { // משמעות + תוצאה • T1 a1(12), a11(10); //הגדרת 2 מערכים של • //בגודל 12 ו-10 double • T2 a2(10); // 10 בגודלintהגדרת מערך של • a2 = a11; // Syntax error • a1 = a11; // O.K. • a1[5] = a2[4]; // O.K. • cout << a1; // הדפסת מערך שלם • constT1 ca1(a11); // הגדרת מערך קבוע • // עם אתחול • ca1 = a11; // Syntax error • ca1[2] = a11[3]; // Syntax error • a11[3] = ca1[2]; // O.K. • doublec_array[] = {0.5, -7, 3.14, 0.3}; • // "C הגדרת "מערך • T1 a12(c_array, 4); // הגדרת מערך ואתחולו • // "C ע"י "מערך • T3 a3; // בגודל5double הגדרת מערך של • T4 a4; // בגודל8double הגדרת מערך של • a3[1] = a4[2]; // O.K. • a3 = a4; // Syntax error • a4 = a3; // Syntax error • a1 = a4; // O.K. • return 0; • } • catch (Bad_Indexexc) { • cerr << exc; //Bad-Index value is ... :פלט • } • } מבוא לתכנות מערכות - 234122

  15. פתרון • typedef Array<double> T1; • typedef Array<int> T2; • typedefSizedArray<double, 5> T3; • typedefSizedArray<double, 8> T4; • classBadIndex { • intindex; • public: • BadIndex(int i) : index(i) {} • friendostream& operator<<(ostream& os, constBadIndex& b); • }; • ostream& operator<<(ostream& os, constBadIndex& b) { • returnos << "Array index " << b.index << " is out of bounds" << endl; • } מבוא לתכנות מערכות - 234122

  16. פתרון • classArrayBase { • protected: • intsize; • boolisLegal(int index) const { • returnindex>=0 && index<size; • } • public: • ArrayBase(intsz): size(sz) { } • intgetSize() const { • returnsize; • } • }; מבוא לתכנות מערכות - 234122

  17. פתרון • template<classT>classArray: publicArrayBase { • T* elements; voidfillArray(T* data,intsz){ • elements= newT[sz]; • size= sz; • for(int i=0;i<sz;i++) • elements[i] = data[i];}public: • Array(intsz):ArrayBase(sz), elements(newT[sz]) {} • Array(constArray<T>& array2) : ArrayBase(array2.size) { • fillArray(array2.elements,size); } • Array(T* array2, intsz) : ArrayBase(sz) { • fillArray(array2,size);} מבוא לתכנות מערכות - 234122

  18. פתרון • ~Array() { delete[] elements; } • T& operator[](int i) { • if (!isLegal(i)) throwBadIndex(i); • returnelements[i]; } • constT& operator[](int i) const { • if (!isLegal(i)) throwBadIndex(i); • returnelements[i];} • array& operator=(const array& other) { • if (this == &other) {return*this; } • delete[] elements; • fillArray(other.elements,other.size()); • return *this;}}; מבוא לתכנות מערכות - 234122

  19. פתרון • template<classT> • ostream& operator<< (ostream& out, constArray<T>& array) { • for(inti=0 ; i<array.getSize() ; i++) • out << array[i] << ' '; • returnout << endl; • } • template <classT> • istream& operator>> (istream& in, Array<T>& array) { • for(inti=0 ; i<array.getSize() ; i++) • in >> array[i]; • returnin; • } • template <classT,intSZ> • classArraySize: publicArray<T>{ • public: • ArraySize() : Array<T>(SZ) {}; • }; מבוא לתכנות מערכות - 234122

  20. שאלה 3 • מה מדפיסה התכנית הבאה? intmain() { cout << "--1--" << endl; A<int> a; cout << "--2--" << endl; A<double> a1; cout << "--3--" << endl; B<int> b(a); cout << "--4--" << endl; B<int> b1(b); cout << "--5--" << endl; C c(a); cout << "--6--" << endl; B<int>& b2 = c; cout << "--7--" << endl; return 0; } #include<iostream>usingnamespacestd;template<classT>classA { public: A() { cout << "A::A()" << endl; } A(constA& a) : i(a.i) { cout << "A::A(A&)" << endl; } private: Ti; };template<classT> classB { public: B(A<T> aa) : a(aa) { cout << "B::B(A)" << endl; } B(constB& b) : a(b.a) { cout << "B::B(B&)" << endl; } A<T> a;};classC: publicB<int> { public: C(A<int> aa) : B<int> (aa), a(aa) { cout << "C::C(A aa)" << endl; } ~C() { cout << "C::~C()" << endl; } A<int> a; }; מבוא לתכנות מערכות - 234122

  21. פתרון • יודפס: --5-- A::A(A&) A::A(A&) A::A(A&) B::B(A) A::A(A&) C::C(A aa) --6-- --7-- C::~C() --1-- A::A() --2-- A::A() --3-- A::A(A&) A::A(A&) B::B(A) --4-- A::A(A&) B::B(B&) מבוא לתכנות מערכות - 234122

  22. שאלה 4 • הגדר מחלקה/מחלקות הנדרשות בקובץ Array.h על מנת שקטע הקוד הבא יעבור הידור (קומפילציה). • שים לב: רק הצהרת המחלקה/ות נדרשת - ללא מימוש הפונקציות. יש להניח שבמימוש המחלקה ישנם מצביעים. מבוא לתכנות מערכות - 234122

  23. קטע הקוד for (int i = 0; i < 20; i++) { cin >> arr[i]; sum += arr[i]; } cout << "Sum is:" << sum << endl; min = arr[0]; for (i = 1; i < 20; i++) if (arr[i] < min) min = arr[i]; cout << "Min is: " << min << endl; if (min == arr[0]) cout <<"The first Array is the minimum"<<endl; const Array<double> c_arr = sum; for (int i = 0; i < c_arr.size(); i++) { cout <<"Element #"<<i<<": "<<c_arr[i]<<endl; } delete a1; Array<A> arr_A(7); Array<A> arr_A2 = arr_A; return 0; } #include"Array.h" #include"iostream.h" class A { inta; public: A(intaa = 0) : a(aa) {} };intmain() { Array<int> *a1 = new Array<int>(3); //An array with 3 elements of type int Array<double> arr[20]; //An array of 20 Arrays, each one of them //is of 100 elements of type double Array<double> sum(100); //An Array of 100 elements of type double Array<double> min(100); //An Array of 100 elements of type double sum[0] = 10; sum[1] = 20; sum[2] = 30; מבוא לתכנות מערכות - 234122

  24. פתרון • #ifndef __ARRAY_H_ • #define __ARRAY_H_ • template<classT> • classArray { • public: • Array(int size = 100); • constT& operator[](int i) const; • T& operator[](int i); • Array& operator+=(constArray& arr); • intsize() const; • Array(constArray& src); • Array& operator=(constArray& src); • ~Array(); • private: • //... • }; מבוא לתכנות מערכות - 234122

  25. פתרון • // the next operators are global functions • template<classT> • ostream& operator<<(ostream& out, constArray<T>& arr); • template<classT> • istream& operator>>(istream& inp, Array<T>& arr); • // the next operators may be implemented as member functions • template<classT> • booloperator<(constArray<T>& left, constArray<T>& right); • template<classT> • booloperator==(constArray<T>& left, constArray<T>& right); • #endif//__ARRAY_H_ מבוא לתכנות מערכות - 234122

More Related