220 likes | 240 Views
תכנות מונחה עצמים Object Oriented Programming (OOP). אתגר מחזור ב'. classes. הגדרת מחלקה, עקרונות הסתרת מידע: public ו- private בניית עצמים והריסתם: Constructor Copy c’tor Destructor רשימות אתחול מחלקות המכילות עצמים ממחלקות אחרות Friend Static members.
E N D
תכנות מונחה עצמיםObject Oriented Programming (OOP) אתגר מחזור ב'
classes • הגדרת מחלקה, עקרונות הסתרת מידע: public ו-private • בניית עצמים והריסתם: • Constructor • Copy c’tor • Destructor • רשימות אתחול • מחלקות המכילות עצמים ממחלקות אחרות • Friend • Static members
מחלקות מקוננותמחלקות המכילות עצמים ממחלקות אחרות class String { public: String(const char *s=“”); // c’tor + default c’tor String(const String& s); // copy c’tor ~String() {delete []str;} // d’tor private: char *str; }; class Name { public: Name(){} // default c’tor Name(const String &f, const String &l): first(f), last(l){} //c’tor Name(const Name &n): first(n.first), last(n.last){} // copy c’tor private: String first; String last; };
מחלקות מקוננות • המחלקה Name יכולה לגשת רק ל-public של String • סדר הפעלת constructors: • קודם של העצמים הפנימיים, אחר כך המחלקה החיצונית • סדר הקריאה ל-destructors הפוך • ניתן להגדיר מחלקה פנימית בתוך המחלקה החיצונית • בחלק ה-public או ב-private לפי הצורך
friend • פונקציה שמחלקה מסוימת מגדירה אותה כ-friend תוכל לגשת לחלק ה-private של אותה מחלקה class A { private: int x; }; ------------------------------------- class B { public: void f(const A &a) {y = a.x;} // error private: int y; }; ------------------------------------- void print(const A &a) { cout<< a.x; // error }
friend class A { public: friend void print(const A &a); friend void B::f(const A &a); private: int x; }; ---------------------------------------- class B { public: void f(const A &a) {y = a.x;} // OK private: int y; }; ---------------------------------------- void print(const A &a) { cout<< a.x; // OK }
friend • מחלקה יכולה גם להגדיר שמחלקה שלמה אחרת היא friend שלה ואז כל הפונקציות מאותה מחלקה יכולות לגשת ל-private class A { public: friend class B; private: int x; };
friend • אם לא משתמשים ב-friend אפשר להגדיר פונקציות get ו/או set • יחס החברות הוא לא הדדי. כלומר – אם מחלקה A מגדירה את B כחברה שלה אז B יכולה לגשת ל-private של A אבל לא להיפך
חברי מחלקה סטטייםstatic members • כאשר אחד ממשתני המחלקה מוגד כסטטי אז יש עותק אחד לכל העצמים מאותה מחלקה • יש להגדיר את המשתנה הסטטי מחוץ למחלקה class A { { public: A(int i) {x=i; count++;} ~A() {count--;} int get_count() {return count;} private: int x; static int count; }; int A::count = 0;
חברי מחלקה סטטייםstatic members int main() { A a1(1), a2(2), a3(3); cout<< “the number of A objects = “ << a2.get_count() << endl; return 0; } • משתנה סטטי קיים גם ללא אובייקטים. כדי שנוכל לגשת אליהם גם לא דרך אובייקט (כמו בדוגמא הנ"ל עם הפונקציה get_count) אפשר להשתמש בפונקציה סטטית • פונקציה סטטית לא מקבלת את this כפרמטר והיא יכולה לגשת רק למשתנים סטטיים של המחלקה
חברי מחלקה סטטייםstatic members • כך יכולנו להגדיר class A { { public: A(int i) {x=i; count++;} ~A() {count--;} static int get_count() {return count;} private: int x; static int count; }; • והשימוש היה כך: cout<< “the number of A objects = “ << A::get_count() << endl;
classes • הגדרת מחלקה, עקרונות הסתרת מידע: public ו-private • בניית עצמים והריסתם: • Constructor • Copy c’tor • Destructor • רשימות אתחול • מחלקות המכילות עצמים ממחלקות אחרות • Friend • Static members
Overloading arithmetic operators שיטה 1: פונקציה חיצונית point operator+(const point& p1, const point& p2) // the sum of p1 and p2 is returned. { double x_sum, y_sum; x_sum = (p1.get_x() + p2.get_x()); y_sum = (p1.get_y() + p2.get_y()); point sum(x_sum, y_sum); return sum; }
Overloading arithmetic operators • שיטה 2: member function point point::operator+(const point& p2) const // the sum of activating object (p1) and argument p2 is returned. { double x_sum, y_sum; x_sum = (x + p2.get_x()); y_sum = (y + p2.get_y()); point sum(x_sum, y_sum); return sum; }
Overloading arithmetic operators • מתי נכתוב אופרטור כפונקציה חיצונית ומתי כפנימית?
Overloading comparison operators bool operator==(const point& p1, const point& p2) // the return is true if p1 and p2 are identical; otherwise return is false. { return (p1.get_x() == p2.get_x()) && (p1.get_y() == p2.get_y()); }
Overloading comparison operators bool operator!=(const point& p1, const point& p2) // the return is true if p1 and p2 are NOT identical; otherwise return is false. { return (p1.get_x() != p2.get_x()) || (p1.get_y() != p2.get_y()); //or return !(p1== p2); }
Overloading I/O operators • Input (>>) & Output (<<) for a new class: << • Q1: how to use this overloaded operator? ostream& operator<<(ostream& outs, const point& source) // The x and y coordinates of source have been // written to outs. The return value is the ostream outs. { outs << source.get_x( ) << " , " << source.get_y( ); return outs; } cout << p ;
Overloading I/O operators • Input (>>) & Output (<<) for a new class: << • Q2: why is outs a reference parameter but NOT const? ostream& operator<<(ostream& outs, const point& source) // The x and y coordinates of source have been // written to outs. The return value is the ostream outs. { outs << source.get_x( ) << " " << source.get_y( ); return outs; } Need change actual argument cout
Overloading I/O operators • How to overload the input operator >> ? • Input (>>) & Output (<<) for a new class: >> • NO const for both istream and point • Problem: send input directly to private members! istream& operator>>(istream& ins, point& target) // The x and y coordinates of target have been // read from ins. The return value is the istream ins. // Library facilities used: iostream { ins >> target. x >> target.y; return ins; }
Friend Function • Solution: use a friend function for overloading the input function class point { public: … … // FRIEND FUNCTION friend istream& operator>>(istream& ins, point& target); private: … };