Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε

Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε

ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου.

Παρόμοιες παρουσιάσεις


Παρουσίαση με θέμα: "ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου."— Μεταγράφημα παρουσίασης:

1 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.1 Είσοδος & Έξοδος στη C++ Ι #include void main() { cout<< “Hello, World“ << endl; } Το αρχείο iostream.h πρέπει να περιλαμβάνεται σε κάθε πηγαίο πρόγραμμα που χρησιμοποιεί λειτουργίες ροής εισόδου – εξόδου. Αυτό το αρχείο κεφαλίδας ορίζει μεταξύ άλλων το αντικείμενο cout που αναπαριστά την τυπική έξοδο. Κάθε δεδομένο που στέλνεται στο cout εμφανίζεται στο τερματικό ή στέλνεται σε αρχείο στην περίπτωση ανακατεύθυνσης της τυπικής εξόδου. Στέλνοντας στη ροή εξόδου το αντικείμενο endl τυπώνεται ο χαρακτήρας νέας γραμμής και εκκενώνεται η προσωρινή περιοχή αποθήκευσης της ροής εξόδου (stream buffer).

2 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.2 Είσοδος & Έξοδος στη C++ ΙΙ Για να σταλούν δεδομένα στη ροή εξόδου χρησιμοποιείται ο τελεστής <<. Μπορούμε να έχουμε αλυσίδα λειτουργιών εξόδου στην ίδια ροή: cout<< “The value of pi is approx. “ << << endl; Μπορούν τα δεδομένα αντί για την τυπική έξοδο να σταλούν σε ένα αρχείο. #include ofstream os(“output.dat”); os << “The value of pi is approx. “ << << endl;

3 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.3 Είσοδος & Έξοδος στη C++ ΙΙΙ Το αρχείο iostream.h ορίζει επίσης την κλάση istream και ένα αντικείμενο cin για ανάγνωση από την τυπική είσοδο (είτε πληκτρολόγιο ή από ανακατευθυνόμενο αρχείο). Ο τελεστής >> χρησιμοποιείται για την ανάγνωση δεδομένων. double x; cin>> x; Για κάθε δεδομένο που διαβάζεται με τον τελεστή >> αγνοούνται τα κενά που προηγούνται. Αν θέλουμε να διαβάσουμε ένα μόνο χαρακτήρα χωρίς να αγνοήσουμε την πιθανότητα του κενού, τότε καλούμε την get. char ch = cin.get(); Μπορούμε αν θέλουμε να «ανιχνεύσουμε» τον επόμενο χαρακτήρα χωρίς να τον καταναλώσουμε από τη ροή εισόδου:

4 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.4 Είσοδος & Έξοδος στη C++ ΙV double x; char aChar; char ch = cin.peek(); if (isdigit(ch)) cin >> x; else cin >> aChar; Συνάρτηση που ελέγχει αν υπάρχει αποτυχία στην ανάγνωση δεδομένου από τη ροή εισόδου (α) λόγω ασυμφωνίας τύπων ή (β) λόγω τέλους αρχείου: 

5 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.5 Είσοδος & Έξοδος στη C++ V Στο παρακάτω πρόγραμμα το loop τερματίζει όταν διαβαστεί συμβολοσειρά που δεν είναι αριθμός ή στο τέλος αρχείου. double t = 0; int n = 0; while (!cin.fail()) { double x; cin >> x; if (!cin.fail()) { t += x; n++; } } if (n > 0) cout << “average: “ << t/n <

6 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.6 Είσοδος & Έξοδος στη C++ VΙ Ανάγνωση από αρχείο: #include ifstream is(“input.dat”); is >> x; if (is.fail())....;

7 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.7 Η συνάρτηση main πρωτότυπο της συνάρτησης main: void main (int argc, char* argv[]); ο αριθμός των παραμέτρωνπίνακας δεικτών χαρα- κατά την κλήση του προγ/τοςκτήρα που αντιστοιχούν στις συμβολοσειρές των παραμέτρων του προγ/τος

8 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.8 Προγραμματίζετε με assertions!! H macro assert ορίζεται στο assert.h και επιτρέπει των ορισμό συνθηκών που ο έλεγχός τους έχει ως αποτέλεσμα τον εντοπισμό του αριθμού γραμμής όπου παρουσιάζεται κάποιο λάθος χρόνου εκτέλεσης. //#define NDEBUG #include //... y = f(x); #ifndef NDEBUG assert (y>=0); #endif z = sqrt(y);

9 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.9 Ορισμός Κλάσης (Τάξης) Ι ΚΑΛΗ ΠΡΑΚΤΙΚΗ ΟΡΙΣΜΟΥ ΚΛΑΣΕΩΝ (Η C++ ΔΙΝΕΙ ΚΑΙ ΑΛΛΕΣ ΔΥΝΑΤΟΤΗΤΕΣ) ΔΗΛΩΝΕΤΕ ΤΙΣ ΛΕΙΤΟΥΡΓΙΕΣ (ΣΥΝΑΡΤΗΣΕΙΣ) ΣΤΟ PUBLIC ΜΕΡΟΣ ΤΟΥ ΟΡΙΣΜΟΥ ΤΗΣ ΚΛΑΣΗΣ ΔΗΛΩΝΕΤΕ ΤΑ ΠΕΔΙΑ ΔΕΔΟΜΕΝΩΝ ΣΤΟ PRIVATE ΜΕΡΟΣ ΤΟΥ ΟΡΙΣΜΟΥ ΤΗΣ ΚΛΑΣΗΣ ΓΡΑΦΕΤΕ ΤΗΝ ΥΛΟΠΟΙΗΣΗ ΤΩΝ ΛΕΙΤΟΥΡΓΙΩΝ ΑΜΕΣΩΣ ΜΕΤΑ ΤΟΝ ΟΡΙΣΜΟ ΤΗΣ ΚΛΑΣΗΣ ΠΑΡΑΔΕΙΓΜΑ ΠΑΡΑΔΕΙΓΜΑ οι λειτουργίες αυτές δηλώνονται class Mailbox ως public γιατί καλούνται { για αντικείμενα mailbox public: οπουδήποτε μέσα στο πρόγραμμα void add(Message); Message get_current(); void delete_current(); //... }

10 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.10 Ορισμός Κλάσης (Τάξης) ΙΙ ΣΤΗ C++ TA ANTIKEIMENA EINAI ΑΠΛΕΣ ΜΕΤΑΒΛΗΤΕΣ ΠΟΥ Ο ΤΥΠΟΣ ΤΟΥΣ ΕΙΝΑΙ Η ΚΛΑΣΗ ΑΠΟ ΤΗΝ ΟΠΟΙΑ ΕΧΟΥΝ ΔΗΜΙΟΥΡΓΗΘΕΙ κώδικας που αφαιρεί ένα ΠΑΡΑΔΕΙΓΜΑ ΠΑΡΑΔΕΙΓΜΑμήνυμα από ένα mailbox Mailbox mbox;και στη συνέχεια το χρη- Message msg;σιμοποιεί msg = mbox.get_current(); msg.play(); ΟΙ ΛΕΙΤΟΥΡΓΙΕΣ ΜΠΟΡΕΙ ΝΑ ΚΑΛΟΥΝΤΑΙ ΜΕ ΠΑΡΑΜΕΤΡΟΥΣΠΑΡΑΔΕΙΓΜΑ mbox.add(msg);

11 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.11 Ορισμός Κλάσης (Τάξης) ΙΙI ΚΛΗΣΗ ΛΕΙΤΟΥΡΓΙΑΣ ΓΙΑ ΕΝΑ ΑΝΤΙΚΕΙΜΕΝΟ–ΣΥΝΤΑΞΗ: αντικείμενο.λειτουργία(παράμετροι); ΔΗΛΩΣΗ ΠΕΔΙΩΝ ΔΕΔΟΜΕΝΩΝ ΣΤΗΝ ΚΛΑΣΗ: ΠΑΡΑΔΕΙΓΜΑ ΠΑΡΑΔΕΙΓΜΑ class Dateδηλώνονται στο private μέρος του {ορισμού της κλάσης για να διασφαλι- public:στεί ότι θα είναι προσβάσιμες μόνο //...από τις λειτουργίες της κλάσης Date private:και από πουθενά αλλού int _day; λέμε ότι ο ορισμός της κλάσης int _month; δίνει μια μη ολοκληρωμένη πε- int _year; ριγραφή της κατάστασης αντικει } μένων Στην πραγματικότητα το σύνολο των σωστών καταστάσεων των αντικειμένων της Date είναι ένα υποσύνολο του συνόλου των καταστάσεων που περιγράφεται στον ορισμό της κλάσης (πρέπει π.χ. _day <= 31)

12 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.12 Ορισμός Κλάσης (Τάξης) ΙV Η κλάση Date είναι παρόμοια με τον ορισμό της στη C ως structure struct { int day; int month; int year; }; Παρόλα αυτά τα structures στη C δεν παρέχουν τη δυνατότητα ελέγχου πρόσβασης στα δεδομένα. Αυτά μπορούν να αλλάξουν από οπουδήποτε μέσα στο πρόγραμμα: struct date birthday = {31, 3, 1961}; //... birthday.day = birthday.day + 1;

13 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.13 Ορισμός Κλάσης (Τάξης) V Ο αντίστοιχος κώδικας στη C++ απλά δεν θα μεταφραζόταν: Date birthday; birthday._day = birthday._day + 1;//ERROR Αλλαγή ημερομηνίας μπορεί να γίνει στη C++ μόνο με κλήση της κατάλληλης λειτουργίας που έχει γράψει ο συγγραφέας της κλάσης Date. Μπορεί δηλαδή να γίνει μόνο με ελεγχόμενο τρόπο. Πως γράφουμε την υλοποίηση λειτουργιών;

14 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.14 Ορισμός Κλάσης (Τάξης) VΙ Έστω ότι θέλουμε να αλλάξουμε την τιμή μιας ημερομηνίας b με μία άλλη που αντιστοιχεί σε 30 ημέρες μετά. Αυτό γίνεται με την κλήση της b.advance(30); αλλά προφανώς πρέπει να έχει δηλωθεί και η κατάλληλη συνάρτηση στον ορισμό της κλάσης class Date { public: void advance(int nday); //... };

15 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.15 Ορισμός Κλάσης (Τάξης) VΙI και στη συνέχεια ακολουθεί η υλοποίηση της συνάρτησης τελεστής εμβέλειας void Date::advance(int nday) {//μετατροπή σε Ιουλιανή ημερομηνία long j = dat2jul(_day, _month, _year); //πρόσθεση n ημερών j += nday; //μετατροπή από Ιουλιανή ημερομηνία jul2dat(j, _day, _month, _year); } Ο τελεστής εμβέλειας χρησιμοποιείται για να καθορίσει σε ποια κλάση ανήκει η λειτουργία advance

16 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.16 Ορισμός Κλάσης (Τάξης) VΙIΙ ΤΟ ΣΗΜΑΝΤΙΚΟ ΔΕΝ ΕΙΝΑΙ ΟΙ ΛΕΠΤΟΜΕΡΕΙΕΣ ΤΗΣ ΥΛΟΠΟΙΗΣΗΣ ΑΛΛΑ ΤΟ ΓΕΓΟΝΟΣ ΟΤΙ ΜΕ ΤΗΝ ΚΛΗΣΗ ΤΗΣ Η ΣΥΝΑΡΤΗΣΗ advance ΑΛΛΑΖΕΙ ΤΙΣ ΤΙΜΕΣ ΤΩΝ _day, _month, _year. ΠΟΙΕΣ ΤΙΜΕΣ ΟΜΩΣ ΤΕΛΙΚΑ ΑΛΛΑΖΕΙ ΑΝ ΛΑΒΟΥΜΕ ΥΠΟΨΗ ΟΤΙ ΜΠΟΡΕΙ ΝΑ ΥΠΑΡΧΟΥΝ ΠΟΛΛΑ ΑΝΤΙΚΕΙΜΕΝΑ Date; Η ΣΥΝΑΡΤΗΣΗ ΑΛΛΑΖΕΙ ΤΙΣ ΤΙΜΕΣ ΠΟΥ ΑΝΗΚΟΥΝ ΣΤΟ ΑΝΤΙΚΕΙΜΕΝΟ ΓΙΑ ΤΟ ΟΠΟΙΟ ΚΑΛΕΙΤΑΙ Η ΛΕΙΤΟΥΡΓΙΑ: b.advance(30); ΣΤΗ C++ ΠΑΝΤΑ ΟΙ ΛΕΙΤΟΥΡΓΙΕΣ ΕΦΑΡΜΟΖΟΝΤΑΙ ΣΕ ΚΑΠΟΙΟ ΑΝΤΙΚΕΙΜΕΝΟ ΠΟΥ ΟΥΣΙΣΤΙΚΑ ΑΠΟΤΕΛΕΙ ΤΗΝ ΥΠΟΝΟΟΥΜΕΝΗ ΠΑΡΑΜΕΤΡΟ ΤΗΣ ΛΕΙΤΟΥΡΓΙΑΣ. ΜΙΑ ΛΕΙΤΟΥΡΓΙΑ ΟΜΩΣ ΜΠΟΡΕΙ ΝΑ ΕΧΕΙ ΚΑΙ ΦΑΝΕΡΕΣ ΠΑΡΑΜΕΤΡΟΥΣ ΚΑΙ ΣΤΟ ΠΑΡΑΔΕΙΓΜΑ ΜΑΣ ΜΙΑ ΤΕΤΟΙΑ ΕΙΝΑΙ ΤΟ 30. ΣΤΗ C++ ΟΙ ΠΡΟΓΡΑΜΜΑΤΙΣΤΕΣ ΑΠΟΚΑΛΟΥΝ ΤΙΣ ΛΕΙΤΟΥΡΓΙΕΣ ΣΥΝΑΡΤΗΣΕΙΣ ΜΕΛΗ ΚΑΙ ΤΑ ΠΕΔΙΑ ΔΕΔΟΜΕΝΩΝ ΤΑ ΑΠΟΚΑΛΟΥΝ ΔΕΔΟΜΕΝΑ ΜΕΛΗ. Ο ΤΕΛΕΣΤΗΣ. ΧΡΗΣΙΜΟΠΟΙΕΙΤΑΙ ΓΙΑ ΠΡΟΣΒΑΣΗ ΕΙΤΕ ΣΤΙΣ ΣΥΝΑΡΤΗΣΕΙΣ ΜΕΛΗ ΕΙΤΕ ΣΤΑ ΔΕΔΟΜΕΝΑ ΜΕΛΗ.

17 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.17 Ορισμός Κλάσης (Τάξης) ΙX CONSTANT ΛΕΙΤΟΥΡΓΙΕΣ class Date { public: void advance(int); void print() const; //... }; σημαίνει ότι η συγκεκριμένη λειτουργία δεν αλλάζει την κατάσταση του αντικειμένου αλλά χρησιμοποιείται μόνο για πρόσβαση στα δεδομένα του void Date::print() const { //... }

18 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.18 Ορισμός Κλάσης (Τάξης) X ΣΥΝΑΡΤΗΣEIΣ ΑΠΛΗΣ ΠΡΟΣΠΕΛΑΣΗΣ ΠΕΔΙΩΝ ΔΕΔΟΜΕΝΩΝ class Date { public: int month() const; //... private: int _day; int _month; είναι συναρτήσεις που απλά int _year; επιστρέφουν την τιμή μιας //... private μεταβλητής }; int Date::month() const { return _month; }

19 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.19 Ορισμός Κλάσης (Τάξης) XI Για το συγγραφέα της κλάσης είναι κάποιος επιπλέον κόπος η συγγραφή τόσο του private δεδομένου μέλους όσο και της αντίστοιχης public συνάρτησης προσπέλασης της τιμής του. Για τον προγραμματιστή που χρησιμοποιεί την κλάση αντί να γράψει d._month γράφει d.month(). Το σημαντικό είναι ότι με αυτόν τον τρόπο η τιμή του δεδομένου μέλους έχει γίνει read only για το υπόλοιπο πρόγραμμα εκτός της κλάσης. Σε περίπτωση λάθους δε χρειάζεται να ερευνηθεί όλο το πρόγραμμα, αλλά μόνο οι συναρτήσεις της κλάσης. H C++ απαιτεί ένα πεδίο δεδομένων να έχει διαφορετικό όνομα από τη συνάρτηση προσπέλασης και γι΄ αυτό το λόγο χρησιμοποιείται το _. Γράφουμε δηλαδή _month για να διακρίνεται από το month().

20 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.20 Ορισμός Κλάσης (Τάξης) XIΙ ΣΥΝΑΡΤΗΣEIΣ ΓΙΑ ΑΛΛΑΓΗ ΠΕΔΙΩΝ ΔΕΔΟΜΕΝΩΝ void Date::set_month(int m) { if (1<=m && m<=12) _month = m; } Η συνάρτηση set_month δεν δηλώνεται ως const για να μπορεί να αλλάξει τιμή δεδομένου μέλους. Ονομάζεται συνάρτηση αλλαγής δεδομένου μέλους. Όταν χρησιμοποιούμε συναρτήσεις προσπέλασης και αλλαγής πεδίων δεδομένων, αν χρειαστεί να γίνουν αλλαγές στη δομή της κλάσης τότε ο αλλαγές αυτές επηρεάζουν μόνο τις δύο αυτές κατηγορίες συναρτήσεων, που εύκολα μπορούμε να εντοπίσουμε και δεν επηρεάζουν όλο το υπόλοιπο πρόγραμμα.

21 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.21 Ορισμός Κλάσης (Τάξης) XIΙΙ Οι συναρτήσεις αλλαγής πεδίων δεδομένων μπορούν να κάνουν έλεγχο για λάθος τιμές. Έτσι, θα μπορούσε για παράδειγμα στην κλήση b.set_month(13) να γίνει ο σχετικός έλεγχος για λάθος τιμή κάτι που δεν είναι εφικτό αν απλά γράφαμε b._month=13. Το παράδειγμα της κλάσης Date είναι μια καλή περίπτωση κλάσης στην οποία δεν είναι καλή ιδέα να ορίσουμε συναρτήσεις αλλαγής τιμής για κάθε ένα δεδομένο μέλος. Θεωρείστε τις κλήσεις: d.set_day(31); d.set_month(3); d.set_year(1961); Αν η προηγούμενη τιμή του d ήταν 1 Φεβρουαρίου, τότε η κλήση της πρώτης συνάρτησης θέτει στο αντικείμενο d την μη επιτρεπτή τιμή 31 Φεβρουαρίου. Αυτό σημαίνει ότι θα είχαμε καλύτερο έλεγχο της ορθότητας της κατάστασης των αντικειμένων Date αν η συνάρτηση αλλαγής ήταν μία και η κλήση της είχε τη μορφή d.set_date(31,3,1961);

22 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.22 Ορισμός Κλάσης (Τάξης) XIV ΣΥΝΑΡΤΗΣEIΣ INLINE Αν μας ενδιαφέρει η ταχύτητα εκτέλεσης και η συνάρτηση που θέλουμε να γράψουμε είναι απλή τότε μπορούμε να τη δηλώσουμε ως inline π.χ. inline int square(int x) {return x*x;} Αυτή η δήλωση θα έχει ως αποτέλεσμα να μεταφράζει ο μεταγλωττιστής το square(expr) απευθείας σε expr*expr υπό τον όρο ότι πρόκειται για απλή έκφραση χωρίς παράπλευρες επιπτώσεις (π.χ. αλλαγή διεύθυνσης μνήμης). Αν η τιμή της έκφρασης είναι προσωρινά αποθηκευμένη στην temp τότε γίνεται απευθείας υπολογισμός της temp*temp. Έχουμε πιο αποδοτική εκτέλεση κώδικα.

23 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.23 Ορισμός Κλάσης (Τάξης) XV ΣΥΝΑΡΤΗΣEIΣ INLINE inline int Date::month() const {return _month;} Στην περίπτωση της παραπάνω δήλωσης η κλήση d.month() μεταφράζεται ως d._month, δηλαδή έχουμε απευθείας προσπέλαση στο πεδίο δεδομένων και έτσι παράγεται ποιο αποδοτικός κώδικας. Οι inline συναρτήσεις προστατεύουν την κατάσταση των αντικειμένων της κλάσης και ταυτόχρονα αποφεύγουν το overhead που συνεπάγεται οι πολλές κλήσεις συναρτήσεων.

24 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.24 Ορισμός Κλάσης (Τάξης) XVΙ ΣΥΝΑΡΤΗΣEIΣ INLINE Εναλλακτικός τρόπος ορισμού inline συναρτήσεων: class Date { public: int day() const {return _day;} //... private: int _day; //... }; Γενικά ο παραπάνω τρόπος ορισμού δεν θεωρείται μια καλή πρακτική.

25 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.25 Ορισμός Κλάσης (Τάξης) XVΙΙ PRIVATE ΣΥΝΑΡΤΗΣΕΙΣ Αρκετά συχνά χρειάζεται να δηλώσουμε private συναρτήσεις, που χρησιμοποιούνται π.χ. Στην υλοποίηση άλλων συναρτήσεων της κλάσης. class Date { public: //... private: Bool is_leap_year() const; int _day; //... }; Σίγουρα η υλοποίηση τέτοιων συναρτήσεων επηρεάζεται από τη δομή της κλάσης, αν όμως η δομή αυτή αλλάξει τότε οι private συναρτήσεις μπορεί και να μη χρειάζονται με τη νέα δομή ή πρέπει να ξαναγραφυτούν.

26 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.26 Ορισμός Κλάσης (Τάξης) XVΙΙΙ ΔΙΚΑΙΩΜΑ ΠΡΟΣΠΕΛΑΣΗΣ ΣΕ ΔΙΑΦΟΡΕΤΙΚΑ ΣΤΙΓΜΙΟΤΥΠΑ ΚΛΆΣΗΣ Στη C++ οι συναρτήσεις μέλη έχουν το δικαίωμα προσπέλασης στα ιδιωτικά μέλη κάθε αντικειμένου της κλάσης πράγμα που δεν ισχύει με όλες τις αντικειμενοστρεφείς γλώσσες προγραμματισμού. ΠΑΡΑΔΕΙΓΜΑ int Date::compare(Date b) const { int d = _year – b._year; if (d != 0) return d; d = _month – b._month; if (d != 0) return d; return _day – b.d_day; }

27 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.27 Δομητές (Constructors) I Οι ΔΟΜΗΤΕΣ είναι ειδικές συναρτήσεις που ΚΑΛΟΥΝΤΑΙ ΑΥΤΟΜΑΤΑ κατά τη δημιουργία των αντικειμένων. Οι δομητές ΈΧΟΥΝ ΤΟ ΙΔΙΟ ΟΝΟΜΑ ΜΕ ΤΟ ΌΝΟΜΑ ΤΗΣ ΚΛΑΣΗΣ. class Date { public: Date(int d, int m, int y); //... }; Date::Date(int d, int m, int y) : _day(d), _month(m), _year(y) { }

28 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.28 Δομητές (Constructors) II Οι ΔΟΜΗΤΕΣ αρχικοποιούν τα πεδία δεδομένων του αντικειμένου. Ο συμβολισμός _day(d) είναι ισοδύναμος με την ανάθεση _day = d. Επειδή δεν απαιτείται κάτι άλλο από το δομητή το σώμα της συνάρτησης δεν περιέχει κάποια επιπλέον εντολή. Επίσης, οι δομητές δεν επιστρέφουν τιμές. Ο δομητής του παραδείγματος καλείται αυτόματα με τη δήλωση ενός αντικειμένου date: Date d(31, 3, 1961); ΔΙΑΦΟΡΕΣ ΔΟΜΗΤΩΝ ΑΠΟ ΤΙΣ ΥΠΟΛΟΙΠΕΣ ΣΥΝΑΡΤΗΣΕΙΣ Ο δομητής καλείται μόνο μία φορά κατά τη δημιουργία του αντικειμένου. Δεν μπορεί να κληθεί δεύτερη φορά για να «επαναρχικοποιήσει» το αντικείμενο Ο δομητής δεν μπορεί να κληθεί για ένα ήδη υπαρκτό αντικείμενο Ο δομητής δεν μπορεί να κληθεί φανερά όπως οι άλλες συναρτήσεις. Καλείται αυτόματα από τη C++ κατά τη δήλωση του αντικειμένου.

29 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.29 Δομητές (Constructors) III Μεγάλο πλεονέκτημα των ΔΟΜΗΤΩΝ είναι το ότι η ύπαρξή τους απομακρύνει την πιθανότητα μη αρχικοποιημένων μεταβλητών. Αν οριστεί ΔΟΜΗΤΗΣ αποκλείεται να οριστούν αντικείμενα τα οποία δεν θα αρχικοποιούνται. έτσι αν έχει δηλωθεί η Date(int, int, int) τότε η Date d; είναι λάθος Στις κλάσεις μπορεί να ορίζονται περισσότεροι από ένας δομητές αλλά μόνο ένας από αυτούς θα είναι ο πρoκαθορισμένος (default)

30 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.30 Δομητές (Constructors) IV class Date { public: Date(); Date(int d, int m, int y=0); Date(String); //... }; Date::Date(int d, int m, int y) : _day(d), _month(m), _year(y) { if (_year == 0) _year = current year}

31 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.31 Ανώνυμα αντικείμενα Οι δομητές μπορούν να χρησιμοποιηθούν στη δημιουργία αντικειμένων που χρησιμοποιούνται σε υπολογισμούς και μετά δεν μας χρειάζονται: όπως θα γράφαμε στη C int y = x + 10; μπορούμε στη C++ να γράψουμε Date d = Date(31, 3, 1961).advance(x);

32 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.32 Δομητές για αντικείμενα μέλη αντικειμένων Όλα τα αντικείμενα μιας κλάσης πρέπει να δημιουργηθούν ακόμη και αυτά που περιλαμβάνονται ως μέλη σε άλλες κλάσεις. Employee::Employee(String n, int hd, int hm, int hy) : _name(n), _hiredate(hd, hm, hy) { } Ο δομητής αυτός περνάει παραμέτρους στους δομητές των υποαντικειμένων. Τα πεδία που δεν αναφέρονται ρητά στη λίστα αρχικοποίησης όπως π.χ. το _address αρχικοποιούνται από τον προκαθορισμένο δομητή της κλάσης τους. Τα πεδία που ανήκουν σε κλάση που δεν έχει προκαθορισμένο δομητή πρέπει να αρχικοποιηθούν ρητά, αλλιώς ο μεταγλωττιστής θα βγάλει λάθος.

33 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.33 Ο καλός προγραμματιστής... Κάνει πάντα τα δεδομένα μέλη private Τα πεδία δεδομένων προτιμάει να είναι κλάσεις και όχι απλοί τύποι παράδειγμα κακής σχεδίασης: class Emplyee { public: //... private: String _lname; String _fname; char _middle_initial; String _street; String _city; String _state; long _zip; //... };

34 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.34 Ο καλός προγραμματιστής... παράδειγμα καλής σχεδίασης class Name { public: //... private: String _lname; String _fname; char _middle_initial; //... }; class Addressclass Employee{ public: //... private: String _street; Name _name; String _city; Address _address; String _state; Date _hiredate; long _zip; //... //...}; };

35 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.35 Ο καλός προγραμματιστής... Δεν είναι απαραίτητες συναρτήσεις προσπέλασης και αλλαγής τιμής για όλα τα πεδία. Να δηλώνονται οι συναρτήσεις προσπέλασης ως const. Να υιοθετείται ένα standard στυλ ορισμού κλάσεων για να επιτυγχάνεται ικανοποιητική αναγνωσιμότητα. Π.χ. βάζουμε πρώτα το public μέρος, μετά το private μέρος, στο public μέρος αναφέρουμε πρώτα τους δομητές, μετά τις συναρτήσεις αλλαγής τιμής και τέλος τις συναρτήσεις προσπέλασης τιμής και στο private μέρος βάσουμε πρώτα τις συναρτήσεις και μετά τα δεδομένα μέλη Δεν παραλείπει ποτέ να δηλώσει έναν προκαθορισμένο δομητή Δημιουργεί όλα τα υποαντικείμενα πριν από το σώμα του δομητή.

36 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.36 Κληρονομικότητα Ι Παράδειγμα class Point { public: Point(double x=0, double y=0); void move(int dx, int dy); void scale(Point center, double scalefactor); double x() const; double y() const; void plot(GraphicsContext&) const; void print(ostream&) const; //... private: double _x; double _y;}

37 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.37 Κληρονομικότητα ΙI class Polygon { public: Polygon(int); void set_vertex(int i, Point p); void move(double dx, double dy); void scale(Point center, double s); void plot(GraphicsContext& gc) const; Point vertex(int) const; //... private: Array _vertex; };

38 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.38 Κληρονομικότητα ΙII class Triangle : public Polygon { public: Triangle(Point, Point, Point); }; βασική κλάση από την οποία κληρονομεί παράγωγη κλάση

39 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.39 Κληρονομικότητα ΙII Triangle::Triangle(Point a, Point b, Point c) : Polygon(3) {set_vertex(1,a); set_vertex(2, b); set_vertex(3, c); }; Η παράγωγη κλάση μπορεί να κληρονομήσει τη συνάρτηση B::f() χωρίς αλλαγή. Η παράγωγη κλάση μπορεί να αντικαταστήσει την B::f() με τη συνάρτηση D::f() που θα κάνει μια διαφορετική λειτουργία. Η παράγωγη κλάση μπορεί να επεκτείνει την B::f() με την D::f() να καλεί την B::f() και να κάνει και κάποιες επιπλέον λειτουργίες.

40 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.40 Κληρονομικότητα ΙV Επέκταση συνάρτησης – παράδειγμα void ScalableText::scale(Point center, double s) { Text::scale(center, s); _size = _size * s; } Αντικατάσταση συνάρτησης - παράδειγμα class Triangle : public Polygon { public: Triangle(Point, Point, Point); void print(ostream& os) const; }; void Triangle::print(ostream& os) const { }

41 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.41 Πολλαπλή κληρονομικότητα Ι //Παράδειγμα πολλαπλής κληρονομικότητας #include class Circle {int X_center, Y_center; intradius; public: Circle(int x, int y, int r=20){ X_center=x; Y_center=y; radius=r; } void SetCenter(int x, int y){ X_center=x; Y_center=y; } void SetRadius(int r){ radius=r;} int GetRadius(){ return radius; } int GetXCenter(){ return X_center; } int GetYCenter(){υπερφόρτωση return Y_center;τελεστή ++ } void Paint(){ circle(X_center, Y_center, radius); } void operator++(){ radius++; X_center++; Y_center++; } };

42 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.42 Πολλαπλή κληρονομικότητα ΙΙ //Παράδειγμα (ΣΥΝΕΧΕΙΑ) enum COLORS { BLACK, BLUE, GREEN, CYAN,..., WHITE}; class Color {COLORS color; public: Color(COLORS c=BLACK){ color=c; } COLORS GetCol(){ return color; } void SetCol(COLORS c){ color=c; } COLORS operator++(){ color= COLORS((color+1)%getmaxcolor()); } }; class ColorCircle:public Circle, Color { public: ColorCircle(int x, int y, int r=20, COLORS c=RED): Circle(x, y, r), Color(c); {} void Paint(){ setcolor(GetCol()); Circle::Paint(); } }; ColorCircle CircleColor

43 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.43 Πολλαπλή κληρονομικότητα ΙΙI class A; class B1: public A; class B2: public A; class C: public B1, public B2; C B1B2 AA Ο μεταγλωττιστής δημιουργεί δύο αντίγραφα της κλάσης A. Πρόβλημα: αν στην κλάση A υπάρχει ο ορισμός public: int data; τότε για να προσπελασθεί η data μέσα από τη C θα πρέπει να αναφερθεί ως B1::data, αλλιώς η έκφραση θα είναι ασαφής

44 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.44 Πολλαπλή κληρονομικότητα ΙV class A; class B3: virtual public A; class B4: virtual public A; class C: public B3, public B4; D B3B4 A ΠΑΡΑΔΕΙΓΜΑΤΑ: Professor-Author ProfessorAuthor Person Married Couple ManWoman Person

45 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.45 Σχέση κληρονομικότητας Ένα αντικείμενο κλάσης A έχει ένα αντικείμενο κλάσης Β. Το αντικείμενο κλάσης Β δηλώνεται ως μέλος της κλάσης Α. Ένα αντικείμενο κλάσης Β είναι κλάσης Α. Η κλάση Β κληρονομεί από την κλάση Α. ΠΑΡΑΔΕΙΓΜΑΤΑ: Ένα τετράγωνο είναι παραλληλόγραμμο. Η γενέθλια ημερομηνία είναι μία ημερομηνία. Ένα άτομο έχει μία διεύθυνση και μία γενέθλια ημερομηνία.

46 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.46 Κανόνες συμβατότητας τύπων I Δύο μεταβλητές είναι συμβατές κατά τύπο αν το όνομα των τύπων και των δύο είναι το ίδιο. Εξαίρεση: ένας δείκτης σε υπερκλάση είναι συμβατός με οποιοδήποτε δείκτη σε κλάση που προέρχεται από αυτή (υποκλάση). #include void main() { typedef struct { char first; char second;} twoChars; twoCharsstate1; twoCharsstate2; state1.first=‘M’; state1.second=‘N’; state2=state1;//σωστό: οι μεταβλητές είναι του ίδιου τύπου state2.second++; cout<< “Original structure: “ << state1.first << state1.second<< endl << “Changed structure: ”<< state2.first << state2.second<< endl; }

47 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.47 Κανόνες συμβατότητας τύπων IΙ #include void main() { struct { char first; char second;} state1; struct { char first; char second;} state2; state1.first=‘M’; state1.second=‘N’; state2=state1; //λάθος: οι μεταβλητές δεν είναι του ίδιου τύπου state2.second++; cout<< “Original structure: “ << state1.first << state1.second<< endl << “Changed structure: ”<< state2.first << state2.second<< endl; }

48 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.48 Κανόνες συμβατότητας τύπων IΙΙ #include void main() { struct { char first; char second;} state1, state2; state1.first=‘M’; state1.second=‘N’; state2=state1; //σωστό: οι μεταβλητές είναι του ίδιου τύπου state2.second++; cout<< “Original structure: “ << state1.first << state1.second<< endl << “Changed structure: ”<< state2.first << state2.second<< endl; }

49 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.49 Κανόνες συμβατότητας τύπων IV class TwoChars { char first; char second; public: TwoChars(char f,char s){ first=f; second=s; } }; class StateCode { char first; char second; public: StateCode(char f,char s){ first=f; second=s; } }; void main() { StateCode* pState1; TwoChars* pState2; pState1=new StateCode(‘C’, ‘A’); pState2=new TwoChars(‘H’, ‘I’); pState2=pState1; // ΛΑΘΟΣ pState1=pState2;// ΛΑΘΟΣ }

50 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.50 Κανόνες συμβατότητας τύπων V class TwoChars { char first; char second; public: TwoChars(char f,char s){ first=f; second=s; } }; class StateCode:public TwoChars { public: StateCode(char f,char s): TwoChars(f, s) {} }; void main() { StateCode* pState1; TwoChars* pState2; pState1=new StateCode(‘C’, ‘A’); pState2=new TwoChars(‘H’, ‘I’); pState2=pState1; // ΣΩΣΤΟ pState1=pState2;// ΛΑΘΟΣ pState2=new StateCode(‘A’, ‘R’); }

51 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.51 Δυναμική αντιστοίχιση (dynamic binding) - Παράδειγμα #include class Person { protected: char* name; public: Person(char* n){ name=n; } virtual void Print() { cout<<“My name is” <Print(); //καλεί από την Person cout<<“Prints the name of the woman:” <Print(); //καλεί από τη Foreigner }

52 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.52 Μετατροπή Δεδομένων Ι Τι γίνεται όταν έχουμε εντολή απόδοσης τιμής var1=var2 και οι μεταβλητές που βρίσκονται αριστερά και δεξιά του τελεστή = είναι διαφορετικού τύπου; Αυτόματη μετατροπή: μετατροπές που γίνονται αυτόματα από το μεταγλωττιστή σύμφωνα με τους κανόνες μετατροπής δεδομένων της γλώσσας. Παραδείγματα: από int σε float, από float σε double κ.α. Κατ΄απαίτηση προσαρμογή: ο προγραμματιστής ορίζει τον τύπο στον οποίο θα γίνει η μετατροπή με τον τελεστή προσαρμογής (casting) Παράδειγμα μετατροπής μεταξύ βασικών τύπων: var1=int(var2);

53 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.53 Μετατροπή Δεδομένων ΙΙ Μετατροπή μεταξύ δεδομένων βασικών τύπων και αντικειμένων (κλάσεων οριζόμενων από το χρήστη #include const float MTF= ; class Distance { private: int feet; float inches; public: Distance() {feet=0; inches=0.0;} Distance(float meters) { float fltfeet=MTF*meters; feet=int(fltfeet); inches=12*(fltfeet-feet);} Distance(int ft,float in) { feet=ft; inches=in;} void getdist() { cout<<“\n Δώσε τα πόδια: ”; cin>>feet; cout<<“\n Δώσε τις ίντσες: ”; cin>>inches; } void showdist(){ cout<

54 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.54 Μετατροπή Δεδομένων ΙΙI void main() { Distance dist1=2.35; //χρήση δομητή για τη μετατροπή //μέτρων σε Distance cout<<“\ndist1 =”; dist1.showdist(); dist1=1.00; //χρήση δομητή με ένα όρισμα cout<<“\ndist1=”; dist1.showdist(); Distance dist2(5,10.25); //χρήση δομητή με δύο ορίσματα float mtrs=float(dist2); //χρήση συνάρτησης μετατροπής για cout<<“\ndist2=“<

55 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.55 Μετατροπή Δεδομένων ΙV Μετατροπή τύπουΜέλος στονΜέλος στον τύπο προέλευσηςτύπο προορισμού Βασικός σε βασικό(από το μεταγλωττιστή) Βασικός σε κλάσηΔΕΝ ΥΠΑΡΧΕΙΔομητής Κλάση σε βασικόΣυνάρτηση μετατροπήςΔΕΝ ΥΠΑΡΧΕΙ Κλάση σε κλάσηΣυνάρτηση μετατροπήςΔομητής

56 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.56 Έλεγχος ισοδυναμίας τύπων Για να λειτουργεί χρειάζεται η κλάση να έχει τουλάχιστο μία virtual συνάρτηση. Shape* s; if (typeid(s) == typeid(Rectangle*)) // s points to a Rectangle object else // s points to an object of some other class Στις παλιότερες εκδόσεις της C++ χρειάζεται να δημιουργήσετε το δικό σας μηχανισμό ελέγχου ισοδυναμίας τύπων (συναρτήσεις που να επιστρέφουν κάποια ένδειξη του τύπου του αντικειμένου).

57 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.57 Ιεραρχίες κλάσεων Ι Στον αντικειμενοστρεφή προγραμματισμό χρησιμοποιούμε ιεραρχίες κλάσεων για: την περιγραφή μιας κατάταξης αντικειμένων σε κατηγορίες περιγράφουμε τα αντικείμενα σε σχέση με τις μεταξύ τους ομοιότητες και διαφορές αποφεύγοντας την πλήρη περιγραφή, όπου σε αρκετές περιπτώσεις θα υπήρχε επανάληψη κώδικα π.χ. κατηγορίες από τη βιολογία: κλάση ζώα, κλάση φυτά τη δημιουργία παραλλαγών μιας κλάσης, που διαφοροποιούνται σε σχέση με την υλοποίησή τους π.χ. ένας inkject printer μπορεί να κληρονομεί από την κλάση dot- matrix printer, αλλά αντί για ακίδες (αφαιρούνται από την υλοποίηση) διαθέτει μπεκ ψεκασμού την αφαίρεση (γενίκευση) των κοινών στοιχείων ενός αριθμού κλάσεων π.χ.

58 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.58 Ιεραρχίες κλάσεων ΙΙ Αφαίρεση ή γενίκευση (abstraction) Η περιγραφή ενός αριθμού αντικειμένων διαφορετικών κλάσεων από μία νέα κλάση που θα ενσωματώνει τα κοινά τους χαρακτηριστικά με ένα γενικό τρόπο. Όλα τα κοινά μέλη (δεδομένα, συναρτήσεις) θα περιγράφονται στη γενική κλάση όχημα. Η γενική κλάση που συνήθως αποτελείται από virtual συναρτήσεις παρέχει έτσι μία κοινή διασύνδεση και τη δυνατότητα ομοιόμορφης ονοματολογίας σε όλες τις υποκλάσεις. Φυσικά κάθε συνάρτηση της γενικής κλάσης μπορεί να επανακαθορισθεί στις υποκλάσεις όπως χρειάζεται.

59 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.59 Ιεραρχίες κλάσεων ΙΙΙ Virtual συναρτήσεις χρησιμοποιήθηκαν και στο παράδειγμα με τη δυναμική αντιστοίχιση (dynamic binding), αλλά τώρα θα χρησιμοποιήσουμε καθαρά virtual συναρτήσεις (pure virtual functions). Η διαφορά είναι ότι οι καθαρά virtual συναρτήσεις δεν μπορούν να κληθούν για αντικείμενα της κλάσης στην οποία ορίζονται, αλλά μόνο για αντικείμενα κλάσεων όπου επανακαθορίζονται. virtual int pure_function(int number)=0; Μια κλάση που έχει τουλάχιστο μία καθαρά virtual συνάρτηση λέγεται κλάση αφαίρεσης (abstract class). Το χαρακτηριστικό των κλάσεων αφαίρεσης είναι ότι δεν μπορούμε παράγουμε αντικείμενα γι αυτές γιατί δεν το επιτρέπει η γλώσσα. Οι κλάσεις αφαίρεσης χρησιμεύουν μόνο ως βάση κληρονομικότητας για τις υποκλάσεις. Παρόλα αυτά οι κλάσεις αφαίρεσης μπορούν να χρησιμοποιούνται ως τύποι δείκτη που ενδεχομένως περνάνε ορίσματα μέσα σε συναρτήσεις.

60 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.60 Ιεραρχίες κλάσεων ΙV class Printer { public: Printer() {} virtual void Method(char*buffer)=0; virtual int Dpi()=0; }; void function1(Printer pr);//ΛΑΘΟΣ: δεν επιτρέπεται void function2(Printer& pr);//ΣΩΣΤΟ void function3(Printer* pr);//ΣΩΣΤΟ Κάθε κλάση που κληρονομεί από μία κλάση αφαίρεσης και επανακαθορίζονται σε αυτήν όλες οι virtual συναρτήσεις λέγεται ειδική κλάση (concrete class). Τα αντικείμενα των ειδικών κλάσεων μπορούν είτε να χρησιμοποιούνται απευθείας είτε μέσω δείκτη σε κλάση αφαίρεσης, όπως στο παράδειγμα:

61 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.61 Ιεραρχίες κλάσεων V #include class Printer { public: Printer(){} virtual void Method(char*buffer)=0; virtual int Dpi()=0; }; class DotMatrixPrinter:public Printer { int nDots; public: DotMatrixPrinter(int n) { nDots=n; } void Method(char*buffer) { sprintf(buffer,”Dot matrix printer with %d pins”,nDots); } int Dpi() { switch(nDots) { case 8: return 150; case 9: return 160; case 24: return 300; default: return 100; }} }; void main() { char description[40]; DotMatrixPrinter dmp(24);//Αντι dmp.Method(description); cout<Method(description); cout<

62 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.62 Ιεραρχίες κλάσεων VΙ Οι κλάσεις αφαίρεσης είναι πολύ σημαντικές και στον πολυμορφισμό και τη δυναμική αντιστοίχιση. Γενικά είναι προτιμότερο να χρησιμοποιείται κληρονομικότητα από κλάσεις αφαίρεσης παρά από ειδικές κλάσεις. Μία ειδική κλάση ορίζει τη δικιά της αναπαράσταση δεδομένων, που βέβαια δεν πρέπει να δεσμεύει όλες τις υποκλάσεις. Αντίθετα στις κλάσεις αφαίρεσης συνήθως δεν περιλαμβάνουμε δεδομένα ως μέλη ή τουλάχιστο περιλαμβάνουμε μόνο μερικά από αυτά που συμβαίνει να υπάρχουν κοινά σε όλες τις υποκλάσεις. Έτσι, επιτρέπεται στις ειδικές κλάσεις να ορίζουν τα δικά τους ιδιωτικά (private) δεδομένα χωρίς κίνδυνο συγκρούσεων και χωρίς να κληρονομούν άχρηστα δεδομένα άλλων κλάσεων. Η δημιουργία νέων «αφαιρέσεων» δεν είναι απλή υπόθεση αλλά είναι μία τεχνική που πρέπει να καλλιεργήσει ο καλός προγραμματιστής.

63 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.63 Ιεραρχίες κλάσεων VΙΙ ΣΥΝΤΑΓΕΣ ΓΙΑ ΤΗ ΔΗΜΙΟΥΡΓΙΑ ΕΝΟΣ «ΚΑΛΟΥ» ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΕΦΟΥΣ ΠΡΟΓΡ/ΤΟΣ - οι ιεραρχίες κλάσεων πρέπει να είναι περιορισμένες και σε κάποιο ύψος και όχι «ρηχές» και «απλωμένες» - η κλάση στη ρίζα και οι ενδιάμεσες κλάσεις (αν αυτό είναι εφικτό) πρέπει να είναι κλάσεις αφαίρεσης - οι κλάσεις μπορούν να είναι πιο γενικές αν γίνει κατορθωτό να περιορισθεί η χρήση δεδομένων ή η χρήση συγκεκριμένης αναπαράστασης δεδομένων. Αυτό γίνεται αν προσπελαύνονται τα δεδομένα με τη χρήση συναρτήσεων και όχι με απευθείας προσπέλαση. Έτσι, θα μπορεί αν χρειασθεί να αλλαχθεί η αναπαράσταση των δεδομένων με την αλλαγή των συναρτήσεων αφήνοντας ίδιο τον κώδικα όπου χρησιμοποιούνται. - οι κληρονομούσες κλάσεις πρέπει να είναι εξειδικεύσεις

64 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.64 Ιεραρχίες κλάσεων VΙΙΙ ΜΙΑ «ΙΔΑΝΙΚΗ» ΙΕΡΑΡΧΙΑ ΚΛΑΣΕΩΝ ΚΛΆΣΗ ΑΦΑΙΡΕΣΗΣ ΕΙΔΙΚΗ ΚΛΑΣΗ

65 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.65 Ιεραρχίες κλάσεων ΙΧ ΠΑΡΑΔΕΙΓΜΑ ΕΠΕΚΤΑΣΗΣ ΜΙΑΣ ΙΕΡΑΡΧΙΑΣ ΚΛΑΣΕΩΝ

66 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.66 Υπερφόρτωση Τελεστών Ι Τελεστές στους οποίους μπορεί να γίνει υπερφόρτωση + - * / % ^ & | ~ ! = += -= *= /= %= ^= &= |= > >= == != = && || > ->* [] (), Στους τελεστές + - * & μπορούμε να κάνουμε υπερφόρτωση τόσο στη μοναδιαία (ένας τελεσταίος) όσο και στην δυαδική τους μορφή (δύο τελεσταίοι) Παράδειγμα υπερφόρτωσης δυαδικής μορφής τελεστή Vector Vector::operator-(Vector b) const Παράδειγμα υπερφόρτωσης μοναδιαίας μορφής τελεστή Vector Vector::operator-() const {return Vector(-x(), -y()); } Χρήση δυαδικού τελεστή: a – b Xρήση μοναδιαίου τελεστή: -a

67 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.67 Υπερφόρτωση Τελεστών ΙI Τελεστές στους οποίους δεν μπορεί να γίνει υπερφόρτωση..* :: ?: Δεν μπορούμε να δημιουργήσουμε νέους τελεστές Μία συνάρτηση υπερφόρτωσης πρέπει να έχει τουλάχιστο ένα όρισμα (implicit ή explicit) τύπου κλάσης. Δεν μπορούμε να επαναπροσδιορίσουμε τελεστές που εφαρμόζονται μόνο σε αριθμητικούς τελεσταίους (int, double,...) ή μόνο σε δείκτες (char*, X*,...) Η προτεραιότητα και η προσεταιριστικότητα των υπερφορτωμένων τελεστών παραμένει η ίδια με αυτή που διαθέτουν στην προκαθορισμένη τους μορφή Παράδειγμα: Fraction Fraction::operator^(int) const; ΠΡΟΣΟΧΗ ΣΤΗΝ ΠΡΟΤΕΡΑΙΟΤΗΤΑ: το a^2+1 θα εκτελεστεί ως a^(2+1)

68 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.68 Υπερφόρτωση Τελεστών ΙII Χρειάζεται ιδιαίτερη προσοχή στην υπερφόρτωση των τελεστών ++ και – και αυτό γιατί έχουμε και προθεματική μορφή (++x) και επιθεματική μορφή (x++) αυτών των τελεστών. Αν θέλουμε να καλύψουμε και τις δύο περιπτώσεις πρέπει να ορίσουμε δύο συναρτήσεις υπερφόρτωσης Fraction Fraction::operator++();//prefix inc και Fraction Fraction::operator++(int); //postfix Στην περίπτωση της συνάρτησης υπερφόρτωσης για την επιθεματική εκδοχή το όρισμα int χρησιμοποιείται μόνο για να δείξει ότι πρόκειται για επιθεματική μορφή. Η τιμή που περνάει είναι πάντα 0.

69 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.69 Υπερφόρτωση Τελεστών ΙV class Fraction { public: Fraction(long n = 0, long d = 1); Fraction operator+(Fraction) const; //... private: long _num; long _den; }; Fraction::Fraction(long n, long d) : _num(n) _den(d) { } Fraction Fraction::operator+(Fraction b) const { return Fraction(_num * b._den + _den * b._num, _den * b._den); }

70 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.70 Υπερφόρτωση Τελεστών V Στο προηγούμενο παράδειγμα ο constructor Fraction f = 2; μετατρέπει έναν ακέραιο σε κλάσμα. Το ίδιο γίνεται αυτόματα στην αριθμητική έκφραση Fraction g = f + 2; // g = f.operator+(Fraction(2,1)); Χρειάζεται όμως ιδιαίτερη προσοχή γιατί δεν θα μπορούσαμε να χρησιμοποιήσουμε τη φαινομενικά ισοδύναμη έκφραση 2 + f Αυτό συμβαίνει γιατί ο compiler δεν μπορεί να εκτελέσει τη μετατροπή τύπου Fraction(2).operator+(f) Το υπονοούμενο όρισμα (implicit argument) χρησιμοποιείται αποκλειστικά για επιλογή κλάσης και δεν μπορεί να χρησιμοποιηθεί για να γίνει μετατροπή τύπου.

71 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.71 Υπερφόρτωση Τελεστών VΙ Όπως είδαμε στο προηγούμενο παράδειγμα οι constructors που δέχονται ένα μόνο όρισμα εξυπηρετούν και ως συναρτήσεις μετατροπής. Έτσι ο δομητής Fraction(int) μπορεί αυτόματα να μετατρέψει έναν integer σε fraction(με παρονομαστή 1) και βασικά για αυτόματη μετατροπή τύπων χρησιμοποιούνται τέτοιοι δομητές. Τι γίνεται όμως όταν: Ο τύπος στον οποίο θέλουμε να μετατρέψουμε δεν είναι κλάση; Ο τύπος στον οποίο θέλουμε να μετατρέψουμε είναι κλάση την οποία όμως δεν μπορούμε να αλλάξουμε; Ας θεωρήσουμε την μετατροπή από fractions σε αριθμούς κινητής υποδιαστολής. Επειδή ο τύπος double δεν είναι κλάση δεν μπορούμε να δηλώσουμε δομητή γι΄ αυτόν τον τύπο και έτσι δηλώνουμε έναν τελεστή μετατροπής τύπου

72 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.72 Υπερφόρτωση Τελεστών VΙΙ ΠΑΡΑΔΕΙΓΜΑ class Fraction { public: //... operator double() const; }; Fraction::operator double() cnst { return (double) _num / (double) _den; } Fraction f(1, 4); y = sqrt(f); // μετατρέπεται σε y = sqrt(f.operator double())

73 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.73 Γενίκευση (genericity) Ι Ο λόγος που επιδιώκουμε τη δυνατότητα γενίκευσης μιας κλάσης (ή συνάρτησης) είναι το να μπορούμε να κάνουμε τον ορισμό της χωρίς να προσδιορίσουμε τον τύπο ενός ή περισσοτέρων μελών της (παράμετροι). Έτσι, θα μπορούμε να προσαρμόζουμε την κλάση (συνάρτηση) σε διαφορετικές περιπτώσεις χρήσης της χωρίς να επιβάλλεται να την ξαναγράψουμε. ΠΑΡΑΔΕΙΓΜΑ Πρέπει να γράψουμε τον κώδικα για μια ουρά ή μια στοίβα. Μπορούμε εύκολα να ορίσουμε μια ουρά ακεραίων, αλλά τι γίνεται όταν θέλουμε σε μία ουρά να χρησιμοποιούμε αντικείμενα τύπου date; Κάθε γλώσσα αντιμετωπίζει το παραπάνω πρόβλημα και με διαφορετικό τρόπο.

74 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.74 Γενίκευση (genericity) ΙΙ Στη Smalltalk όπου ο έλεγχος τύπων γίνεται σε χρόνο εκτέλεσης ο πολυμορφισμός δεν περιορίζεται στις ιεραρχίες των κλάσεων, αλλά κάθε κλάση μπορεί να αντικατασταθεί από μία άλλη. Έτσι, η γενίκευση γίνεται εύκολα. Στη C++ έχουμε έλεγχο τύπων σε χρόνο μεταγλώττισης. Υπάρχουν δύο τρόποι για την επίτευξη γενίκευσης: με χρήση κληρονομικότητας και πολυμορφισμού ορίζοντας κλάση, που χειρίζεται δείκτες σε αντικείμενα με χρήση παραμετροποιήσιμων τμημάτων κώδικα, των επονομαζόμενων templates Η πρώτη μέθοδος (βλ. παράδειγμα παρακάτω) συνοδεύεται από έναν κίνδυνο με την κατ΄ απαίτηση προσαρμογή (casting) που χρειάζεται στην ανάκτηση του τύπου των αντικειμένων που χειρίζεται η κλάση με τους δείκτες.

75 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.75 Γενίκευση (genericity) ΙΙΙ class GenericObject {}; //stack.h class Stack { GenericObject* data[50]; int nElements; public: Stack() { nElements=0; } void Push(GenericObject* elem); GenericObject* Pop(); int Number(); int Empty(); }; #include “stack.h” //stack.cpp void Stack::Push(GenericObject* elem) { data[nElements]=elem; nElements++; } GenericObject* Stack::Pop() { nElements--; return data[nElements]; } int Stack::Number() { return nElements; } int Stack::Empty() { return (nElements==0); } #include //sta_use.cpp #include “stack.cpp” class IntObj:public GenericObject { public: int data; IntObj(int n) { data=n; } };

76 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.76 Γενίκευση (genericity) ΙV void main() { Stack genericStack; //εισάγουμε νέα αντικείμενα στη στοίβα genericStack.Push(new IntObj(500)); genericStack.Push(new IntObj(1992)); genericStack.Push(new IntObj(33)); genericStack.Push(new IntObj(1024)); //τυπώνει τα στοιχεία της στοίβας καθώς την αδειάζει: //επειδή η συνάρτηση Pop επιστρέφει δείκτη σε //GenericObject, για να προσπελάσουμε μέλος του //αντικειμένου που βγάλαμε χρειάζεται type casting while(!genericStack.Empty()) cout data<

77 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.77 Γενίκευση (genericity) V template //stack.h με template class Stack { T* data[50]; int nElements; public: Stack() { nElements=0; } void Push(T elem); T Pop(); int Number(); int Empty(); }; #include “stack.h” //stack.cpp template void Stack ::Push(T elem) { data[nElements]=elem; nElements++; } template T Stack ::Pop() { nElements--; return data[nElements];} template int Stack ::Number() { return nElements;} template int Stack ::Empty() { return (nElements==0); }

78 ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Τμ. Πληροφορικής, Α.Π.Θ.78 Γενίκευση (genericity) VI #include //sta_use.cpp #include “stack.cpp” void main() { Stack intStack; //εισάγουμε νέα αντικείμενα στη στοίβα intStack.Push(500); intStack.Push(1992); intStack.Push(33); intStack.Push(1024); while(!intStack.Empty()) cout<


Κατέβασμα ppt "ΜΑΘΗΜΑ: ΓΛΩΣΣΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C++ ΔΙΔΑΣΚΩΝ: Π. ΚΑΤΣΑΡΟΣ Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου 2015Παρασκευή, 27 Μαρτίου."

Παρόμοιες παρουσιάσεις


Διαφημίσεις Google