Ειδικά Θέματα Σήμερα Ισότητα Αντικειμένων Friend classes Operator overloading 2 1
Ισότητα Αντικειμένων Πότε δύο αντικείμενα είναι ίσα; Όταν έχουν τις ίδιες τιμές int m, n; if (m == n)... Όταν δείχνουν στις ίδιες τιμές int*p; int* q; //... if(*p = = *q)... 3 Ισότητα Αντικειμένων Όταν είναι οι ίδιοι δείκτες int* p; int* q; //... if (p = = q)... Όταν είναι οι ίδιες αναφορές; (σύγκριση διευθύνσεων μνήμης) ) if (&r == &s) 4 2
Ισότητα Αντικειμένων bool Point::is_equal(Point& b) { return x == bx&& b.x y == by; b.y; bool Rectangle::is_equal(Rectangle& b) { return left_top().is_equal(b.left_top()) && right_bottom().is_equal(b.right_bottom()); Θα πρέπει πάντα η ισότητα μεταξύ αντικειμένων να ελέγχεται από συνάρτηση που γράφει ο προγραμματιστής. 5 Ισότητα Αντικειμένων /1 #include <iostream.h> class CAT { public: CAT(); int GetAge() const { return *itsage; int GetWeight() const { return *itsweight; void SetAge(int age) { *itsage = age; CAT operator=(const CAT &); ; private: int *itsage; int *itsweight; 6 3
Ισότητα Αντικειμένων/2 CAT::CAT() { itsage = new int; itsweight = new int; *itsage = 5; *itsweight = 9; CAT CAT::operator=(const CAT & rhs) { if (this == &rhs) return *this; delete itsage; g; delete itsweight; itsage = new int; itsweight = new int; *itsage = rhs.getage(); *itsweight = rhs.getweight(); return *this; 7 Ισότητα Αντικειμένων /3 int main() { CAT fik frisky; cout << ʺfriskyʹs age: ʺ << frisky.getage() << endl; cout << ʺSetting frisky to 6...\nʺ; frisky.setage(6); CAT whiskers; cout << ʺwhiskersʹ age: ʺ << whiskers.getage() << endl; cout << ʺcopying frisky to whiskers...\nʺ; whiskers = frisky; cout << ʺwhiskersʹ age: ʺ << whiskers.getage() << endl; return 0; frisky's age: 5 Setting frisky to 6... whiskers' age: 5 copying frisky to whiskers... 8 whiskers' age: 6 4
Friend classes Μία κλάση μπορεί να δηλώσει άλλες κλάσεις ως ʺfriend i dclassesʺ. ʺ Μια κλάση μπορεί να δηλώσει εξωτερικές συναρτήσεις ως ʺfriendsʺ. Οι friends έχουν πρόσβαση σε private μέλη 9 Δήλωση friend κλάσης class X { friend class ExternalClass;... ; Όλες οι συναρτήσει μέλη της ExternalClass έχουν πρόσβαση στα μέλη της X 10 5
Δήλωση friend συνάρτησης class X {... friend ret_type func_name (arguments);... ; ret_type func_name (arguments) { Ο ορισμός της συνάρτησης δεν περιέχει τη λέξη friend 11 Λίστα 4 8 Αρχή 7 11 NIL ΤΡ 9 6
Friend functions/1 #include <iostream.h> typedef unsigned long ULONG; typedef unsigned short USHORT; class Part { public: Part():itsPartNumber(1) { Part(ULONG PartNumber): itspartnumber(partnumber){ virtual ~Part(){ ULONG GetPartNumber() const { return itspartnumber; virtual void Display() const ; private: ULONG itspartnumber; ; 13 Friend functions/2 void Part::Display() const { cout << ʺ\nPart Number: ʺ; cout << itspartnumber << endl; class CarPart : public Part { public: CarPart():itsModelYear(94){ CarPart(USHORT year, ULONG partnumber); virtual void Display() const { Part::Display(); cout << ʺModel Year: ʺ; cout << itsmodelyear << endl; private: USHORT itsmodelyear; ; 14 7
Friend functions/3 CarPart::CarPart(USHORT year, ULONG partnumber): itsmodelyear(year), Part(partNumber) { class AirPlanePart : public Part { public: AirPlanePart():itsEngineNumber(1){; AirPlanePart (USHORT EngineNumber, ULONG PartNumber); virtual void Display() const { Part::Display(); cout << ʺEngine No.: ʺ; cout << itsenginenumber << endl; private: USHORT itsenginenumber; ; 15 Friend functions/4 AirPlanePart::AirPlanePart (USHORT EngineNumber, ULONG PartNumber): itsenginenumber(enginenumber), Part(PartNumber) { class PartNode { public: friend class PartsList; PartNode (Part*); ~PartNode(); void SetNext(PartNode * node) { itsnext = node; PartNode * GetNext() const; Part * GetPart() const; 16 8
Friend functions/5 private: Part *itspart; PartNode * itsnext; ; PartNode::PartNode(Part* ppart): itspart(ppart), itsnext(0) { PartNode::~PartNode() { delete itspart; itspart = 0; delete itsnext; itsnext = 0; 17 Friend functions/6 PartNode * PartNode::GetNext() const { return itsnext; Part * PartNode::GetPart() const { if (itspart) return itspart; else return NULL; 18 9
Friend functions/7 class PartsList { public: PartsList(); ~PartsList(); void Iterate(void (Part::*f)()const) const; Part* Find(ULONG & position, ULONG PartNumber) const; Part* GetFirst() const; void Insert(Part *); Part* operator[](ulong) const; ULONG GetCount() const { return eu itscount; ; static PartsList& GetGlobalPartsList() { return GlobalPartsList; private: PartNode * phead; ULONG itscount; static PartsList GlobalPartsList; ; 19 Friend functions/8 PartsList PartsList::GlobalPartsList; PartsList::PartsList(): phead(0), itscount(0) { PartsList::~PartsList() { delete phead; Part* PartsList::GetFirst() const { if (phead) return phead >itspart; else return NULL; 20 10
Friend functions/9 Part * PartsList::operator[](ULONG offset) const { PartNode* pnode = phead; if (!phead) return NULL; if (offset > itscount) return NULL; for (ULONG i=0;i<offset; i++) pnode = pnode >itsnext; return pnode >itspart; 21 Friend functions/10 Part* PartsList::Find(ULONG & position, ULONG PartNumber) const{ PartNode * pnode = 0; p ; for (pnode = phead, position = 0; pnode!=null; pnode = pnode >itsnext, position++) { if (pnode >itspart >GetPartNumber() == PartNumber) break; if (pnode == NULL) return NULL; else return pnode >itspart; 22 11
Friend functions/11 void PartsList::Iterate(void (Part::*func)()const) const { if (!phead) (p return; PartNode* pnode = phead; do (pnode >itspart >*func)(); while (pnode = pnode >itsnext); void PartsList::Insert(Part* ppart) { PartNode * pnode = new PartNode(pPart); PartNode * pcurrent = phead; PartNode * pnext = 0; ULONG New = ppart >GetPartNumber(); ULONG Next = 0; 23 Friend functions/12 itscount++; if (!phead) (p { phead = pnode; return; if (phead >itspart >GetPartNumber() > New) { pnode >itsnext = phead; phead = pnode; return; for (;;) { if (!pcurrent >itsnext) { pcurrent >itsnext = pnode; return; pnext = pcurrent >itsnext; Next = pnext >itspart >GetPartNumber(); 24 12
Friend functions/13 if (Next > New) { pcurrent >itsnext = pnode; pnode >itsnext = pnext; return; pcurrent = pnext; 25 Friend functions/14 class PartsCatalog : private PartsList { public: void Insert(Part *); ULONG Exists(ULONG PartNumber); Part * Get(int PartNumber); operator+(const PartsCatalog &); void ShowAll() { Iterate(Part::Display); private: ; void PartsCatalog::Insert(Part * newpart) { ULONG partnumber = newpart >GetPartNumber(); ULONG offset; if (!Find(offset, partnumber)) PartsList::Insert(newPart); else { 26 13
Friend functions/15 cout << partnumber << ʺ was the ʺ; switch (offset) { case 0: cout << ʺfirst ʺ; break; case 1: cout << ʺsecond ʺ; break; case 2: cout << ʺthird ʺ; break; default: cout << offset+1 << ʺth ; cout << ʺentry. Rejected!\n ; ULONG PartsCatalog::Exists(ULONG PartNumber) { ULONG offset; Find(offset,PartNumber); return offset; 27 Friend functions/16 Part * PartsCatalog::Get(int PartNumber) { ULONG offset; return (Find(offset, PartNumber)); int main() { PartsCatalog pc; Part * ppart = 0; ULONG PartNumber; USHORT value; ULONG choice; while (1) { cout << ʺ(0)Quit (1)Car (2)Plane: ʺ; cin >> choice; if (!choice) break; 28 14
Friend functions/17 cout << ʺNew PartNumber?: ʺ; cin >> PartNumber; if (choice == 1) { cout << ʺModel Year?: ʺ; cin >> value; ppart = new CarPart(value,PartNumber); else { cout << ʺEngine Number?: ʺ; cin >> value; ppart = new AirPlanePart(value,PartNumber); pc.insert(ppart); pc.showall(); return 0; 29 Output (0)Quit (1)Car (2)Plane: 1 New PartNumber?: 1234 Part Number: 1234 Model Year?: 94 (0)Quit (1)Car (2)Plane: 1 New PartNumber?: 4434 Model Year?: 93 (0)Quit (1)Car (2)Plane: 1 New PartNumber?: 1234 Model Year?: 94 1234 was the first entry. Rejected! (0)Quit (1)Car (2)Plane: 1 New PartNumber?: 2345 Model Year?: 93 (0)Quit (1)Car (2)Plane: 0 Model Year: 94 Part Number: 2345 Model Year: 93 Part Number: 4434 Model Year: 93 30 15