Presentation is loading. Please wait.

Presentation is loading. Please wait.

ממיבחניםC שאלות ++. תכנות מונחה עצמים ו C++ (35 נקודות) מערכים בטוחים עליכם לממש מחלקות גנריות עבור "מערכים בטוחים". מערך בטוח הוא מערך המכיל מידע על.

Similar presentations


Presentation on theme: "ממיבחניםC שאלות ++. תכנות מונחה עצמים ו C++ (35 נקודות) מערכים בטוחים עליכם לממש מחלקות גנריות עבור "מערכים בטוחים". מערך בטוח הוא מערך המכיל מידע על."— Presentation transcript:

1 ממיבחניםC שאלות ++

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

3 int main () { try { T1 a1(12), a11(10); // בגודל 12 ו10double הגדרת 2 מערכים של T2 a2(10); // 10 בגודל int הגדרת מערך של a2 = a11; // Syntax error a1 = a11; // O.K. a1[5] = a2[4]; // O.K. cout << a1; // הדפסת מערך שלם const T1 ca1(a11); // הגדרת מערך קבוע עם אתחול ca1 = a11; // Syntax error ca1[2] = a11[3]; // Syntax error a11[3] = ca1[2]; // O.K. double c_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_Index exc) { cerr << exc; // Bad-Index value is... : פלט } typedef T1; typedef T2; typedef T3; typedef T4; more code?

4 typedef array T1; typedef array T2; typedef arraySize T3; typedef arraySize T4; class Bad_Index { int index; public: Bad_Index(int i):index(i){} friend ostream& operator<<(ostream& co,const Bad_Index& b) { return co << "Bad_Index value is " << b.index << endl; } };

5 class arrayBase { int size_; protected: bool legal(int index) const{return index>=0 && index

6 template class array: public arrayBase { T* elem_array; void enter_array(T* ar,int sz){ elem_array = new T[sz]; size(sz); for (int i=0;i

7 ~array(){delete[] elem_array;} T& operator[](int i){ if (!legal(i)) throw Bad_Index(i); return elem_array[i]; } const T& operator[](int i) const{ if (!legal(i)) throw Bad_Index(i); return elem_array[i]; } array& operator=(const array& ar){ if (this == &ar) return *this; delete[] elem_array; enter_array(ar.elem_array,ar.size()); return *this; } friend ostream& operator & ar); friend istream& operator>> (istream& ci, array & ar); };

8 template ostream& operator & ar) { for (int i=0;i> (istream& in, array & ar) { for (int i=0;i> ar.elem_array[i]; return in; }

9 template class arraySize: public array { public: arraySize():array (SZ){}; };

10 חלק א' (15 נק') #include template class A { public: A() { cout << "A::A()" << endl;} A(const A& a) :i(a.i) { cout << "A::A(A&)" << endl;} private: T i; }; template class B { public: B(A aa): a(aa) { cout << "B::B(A)" << endl;} B(const B& b): a(b.a) { cout << "B::B(B&)" << endl;} A a; }; class C : public B { public: C(A aa): B (aa),a(aa) { cout << "C::C(A aa)" << endl;} ~C(){ cout << "C::~C()" << endl;} A a; }; רשמו את הפלט של התוכנית הבאה: void main() { cout << "--1--" << endl; A a; cout << "--2--" << endl; A a1; cout << "--3--" << endl; B b(a); cout << "--4--" << endl; B b1(b); cout << "--5--" << endl; C c(a); cout << "--6--" << endl; B & b2 = c; cout << "--7--" << endl; }

11 פתרון סעיף א': A::A() A::A(A&) B::B(A) A::A(A&) C::C(A aa) A::A() A::A(A&) B::B(A) A::A(A&) B::B(B&) C::~C() --6--

12 חלק ב' (15 נק') הגדר מחלקה/מחלקות הנדרשות בקובץ Array.h על מנת שקטע הקוד הבא יעבור הידור (קומפילציה). שים לב: רק הצהרת המחלקה/ות נדרשת - ללא מימוש הפונקציות. יש להניח שבמימוש המחלקה ישנם מצביעים.

13 חלק ב' (15 נק') #include "Array.h" #include "iostream.h" class A { public: A(int aa = 0) : a(aa) {} private: int a; }; int main () { Array *a1 = new Array (3); // An array with 3 elements of type int Array arr[20]; // An array of 20 Arrays, each one of them // is of 100 elements of type double Array sum(100); // An Array of 100 elements of type double Array min(100); // An Array of 100 elements of type double a1[0] = 10; a1[1] = 20; a1[2] = 30; int i; for (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” <

14 פתרון חלק ב' #ifndef __ARRAY_H_ #define __ARRAY_H_ template class Array { public: Array(int size=100); T operator[](int i) const; T& operator[](int i); Array& operator+=(const T& elem); int size() const; Array(const Array& src); Array& operator=(const Array& src); ~Array(); private: //... };

15 פתרון חלק ב' template ostream& operator & arr); template istream& operator>>(istream& inp, Array & arr); //the next operators may be implemented as member template bool operator & left, const Array & right); template bool operator==(const Array & left, const Array & right); #endif //__ARRAY_H_

16 תכנות מונחה עצמים ו- C++ (40) נקודות. חורף בשאלה זו נעסוק במטריצות בעלות מימדים כלשהם ובפרט במטריצות ריבועיות. בעוד שפעולות שונות ניתנות לביצוע עם מטריצות בגודל כללי (כמו transpose) ישנן פעולות מסוימות הניתנות להפעלה אך ורק על מטריצות ריבועיות. מבין פעולות אלו נתייחס בשאלה לחישוב הדטרמיננטה שלה (determinant). סעיף א (25 נקודות) סעיף זה מתייחס לקטע הקוד הבא: const double EPSILON = ; int main(){ //create two 3*1 matrices (3D vectors) //with entries of type double assigned //with zeros: Matrix m1, m2(3,1); const Matrix m3=m1; //assign values to m1 from the file “matrix_1.dat”: ifstream inputFile(“matrix_1.dat”); inputFile >> m1; inputFile.close(); m2 = m1; m2.getEntry(0,0) = m3.getEntry(1,0); //SYNTAX ERROR !!! m3.getEntry(1,0) = m2.getEntry(0,0); Matrix m4(10,3); inputFile.open(“matrix_4.dat”); inputFile >> m4; inputFile.close(); //create a 3*3 matrix with the multiplication //of m4’s transpose and m4: Matrix m5( m4.transpose() * m4 ); //return 1*3 matrix Matrix secondRow = m5.getRow(1); //return 3*1 matrix Matrix firstColumn = m5.getColumn(0); //create two 3*3 square-matrices. The first equals //to m5, and the second initielied with zeros: SquareMatrix sm6(m5), sm7(3); sm7 = sm6.transpose(); double det6 = sm6.determinant(); double det7 = sm7.determinant(); double diff = (det6 > det7)? det6-det7 : det7-det6 ; if(diff>EPSILON) cout << ”something very strange is going on...”; // save the transposed matrix to the specified file: ofstream outputFile(“transposedMatrix.dat”); outputFile << sm7; outputFile.close(); return 0; }

17 הגדר\י את המחלקות Matrix ו- SquareMatrix באופן מינימאלי כך שהקוד הנ"ל יוכל לעבור קומפילציה (למעט השורה בה מצוין כי חבויה שגיאה). אין להוסיף פונקציונאליות מעבר לנדרש עבור קוד זה ואין צורך לממש את המתודות השונות. בכדי שהמחלקה תהיה ניתנת למימוש יש להניח הנחות מסוימות לגבי ה- type של ה- entries (המוזן ל- template). ציין\י הנחות אלו ופרט\י מדוע הנחות אילו נחוצות.

18 פתרון סעיף א' template class Matrix { protected: T** mat; int x_dim, y_dim; public: Matrix(int x=3, int y=1); Matrix(const Matrix & matrix); Matrix& operator=(const Matrix & matrix); const T& getEntry(int x, int y) const; T& getEntry(int x, int y); Matrix transpose() const; Matrix operator*(const Matrix & matrix) const; Matrix getRow(int x) const; Matrix getColumn(int y) const; ~Matrix(); friend operator >> (ifstream& cin, Matrix & matrix); friend operator & matrix); }; template class SquareMatrix : public Matrix { public: SquareMatrix(int x=3); SquareMatrix(const Matrix & matrix); T& determinant() const; ~SquareMatrix(); };

19 פתרון סעיף א' בכדי שהמחלקה תהיה ניתנת למימוש יש להניח את ההנחות הבאות על ה-type של ה- entries: copy constructor – על מנת שנוכל לממש את ה-copy constructor של Matrix. אופרטור >> על מנת שיהיה ניתן לקלוט data מ-ifstream. אופרטור השמה – על מנת שיהיה אפשר לממש אופרטור השמה של Matrix. אופרטור * ו-+- על מנת שיהיה ניתן לממש את האופרטור * של Matrix. אופרטור +,-,* - לחישוב ה-determinant. default constructor – לאיתחול מערך של entries עבור ה-costructors. אופרטור << - על מנת שנוכל לממש את אופרטור ההדפסה של Matrix.

20 מטריצה סימטרית הינה מטריצה ריבועית השווה ל-transpose של עצמה. בסעיף זה של השאלה הנך נידרש לממש את המחלקה SymetricMatrix. מעבר למתודות הנורשות, למחלקה זו יהיה: בנאי (constructor) המקבל את גודל המטריצה (פרמטר יחיד) ומאתחל אותה כמטריצת היחידה (I) בנאי המקבל SquareMatrix – M כלשהי. היות ו-M אינה סימטרית בהכרח, הבנאי יאתחל את ערכי המטריצה ע"י MTM (שמו לב לכך שביטוי זה הינו סימטרי בהכרח). הגדיר\י וממש\י מחלקה זו. במידה ויש צורך בהנחות נוספות לגבי ה- type של ה- entries ציין\י הנחות אילו. סעיף ב (15 נקודות)

21 template class SymetricMatrix : public SquareMatrix { public: SymetricMatrix (int size); SymetricMatrix (const SquareMatrix & matrix); ~ SymetricMatrix (); }; template SymetricMatrix :: SymetricMatrix (int size): SquareMatrix (size) { for (int i=0;i

22


Download ppt "ממיבחניםC שאלות ++. תכנות מונחה עצמים ו C++ (35 נקודות) מערכים בטוחים עליכם לממש מחלקות גנריות עבור "מערכים בטוחים". מערך בטוח הוא מערך המכיל מידע על."

Similar presentations


Ads by Google