Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language)

Σχετικά έγγραφα
ΗΓλώσσαΠρογραµµατισµού C++ (The C++ Programming Language) Ιστοσελίδα του µαθήµατος. Περιεχόµενα. ηµήτριος Κατσαρός, Ph.D. Ελένη Τουσίδου, Ph.D.

ΗΓλώσσαΠρογραµµατισµού C++ (The C++ Programming Language)

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language)

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language)

Προγραµµατισµός ΙΙ. Ηγλώσσααντικειµενοστραφούς. ιαχείριση Εξαιρέσεων. Εισαγωγή στη ιαχείριση Εξαιρέσεων

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language) Ιστοσελίδα του µαθήµατος. Περιεχόµενα. ηµήτριος Κατσαρός, Ph.D.

Προγραμματισμός Ι. Πίνακες, Δείκτες, Αναφορές και Δυναμική Μνήμη. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Εξαιρέσεις

Οντοκεντρικός Προγραμματισμός

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language)

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language) Ιστοσελίδα του µαθήµατος. Περιεχόµενα. ηµήτριος Κατσαρός, Ph.D. Κλάσεις.

Προγραμματισμός Ι. Εισαγωγή στην C++ Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραµµατισµός ΙΙ. Ηγλώσσααντικειµενοστραφούς. ιδάσκων ηµήτριος Κατσαρός, Τµ. Μηχανικών Η/Υ, Τηλεπικοινωνιών & ικτύων Πανεπιστήµιο Θεσσαλίας

ΗΓλώσσαΠρογραµµατισµού C++ (The C++ Programming Language) Ιστοσελίδα του µαθήµατος. Περιεχόµενα. ηµήτριος Κατσαρός, Ph.D. Ελένη Τουσίδου, Ph.D.

ΗΓλώσσαΠρογραµµατισµού C++ (The C++ Programming Language)

υναµική διαχείριση µνήµης στη C++ Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: ΕΠΛ 132 Αρχές Προγραµµατισµού ΙΙ 2 είκτες

ΠΟΛΥΜΟΡΦΙΣΜΟΣ. 4.1 Κληρονομικότητα και Αρχή της Υποκατάστασης

Οντοκεντρικός Προγραμματισμός

Χειρισµός Σφαλµάτων. Γρηγόρης Τσουµάκας. Τµήµα Πληροφορικής, Αριστοτέλειο Πανεπιστήµιο Θεσσαλονίκης. Έκδοση:

Προγραμματισμός Ι. Κλάσεις και Αντικείμενα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραμματισμός Υπολογιστών με C++

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language)

Διάλεξη 16-17: Πολυμορφισμός (Polymorphism) Διδάσκων: Παναγιώτης Ανδρέου

Αντικειμενοστρεφής Προγραμματισμός

Αντικειμενοστρεφής Προγραμματισμός Διάλεξη 9 : ΕΞΑΙΡΕΣΕΙΣ ΚΑΙ Ο ΧΕΙΡΙΣΜΟΣ ΤΟΥΣ

Σύνθεση και Κληρονομικότητα

Εισαγωγή σε αντικειμενοστραφή concepts. Και λίγη C#

Κλάσεις και Αντικείµενα

Σύνθεση και Κληρονομικότητα

Προγραμματισμός ΙΙ (Java) 4. Διαχείριση εξαιρέσεων

Κλάσεις στη Java. Στοίβα - Stack. Δήλωση της κλάσης. ΗκλάσηVector της Java. Ηκλάση Stack

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language)

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language) Ιστοσελίδα του µαθήµατος. Περιεχόµενα. ηµήτριος Κατσαρός, Ph.D. Αλφαριθµητικά Κλάση string

Κλάσεις στη Java. Παύλος Εφραιμίδης. Java Κλάσεις στη Java 1

Κλάσεις και αντικείμενα #include <iostream.h<

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

ΠΛΗΡΟΦΟΡΙΚΗ ΙI Ενότητα 10: Exceptions handling (Χειρισμός εξαιρέσεων)

Υπερφόρτωση τελεστών

Προγραµµατισµός ΙΙ. Ηγλώσσααντικειµενοστραφούς. ιδάσκων ηµήτριος Κατσαρός, Τµ. Μηχανικών Η/Υ, Τηλεπικοινωνιών & ικτύων Πανεπιστήµιο Θεσσαλίας

Κεφάλαιο 3.1, : Συναρτήσεις I. ( ιάλεξη 11) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Προγραµµατισµός ΙΙ. Ηγλώσσααντικειµενοστραφούς. Συλλογές και Επαναλήπτες. Συλλογές - Collections

6. Εξαιρέσεις στη γλώσσα Java

Βαθμός Σχόλια. lab5 PASS PASS PASS PASS PASS. Οριακά PASS - Καλή δουλειά

Προγραµµατισµός ΙΙ. Ηγλώσσααντικειµενοστραφούς. ιδάσκων ηµήτριος Κατσαρός, Τµ. Μηχανικών Η/Υ, Τηλεπικοινωνιών & ικτύων Πανεπιστήµιο Θεσσαλίας

ΑΠΛΗ ΚΛΗΡΟΝΟΜΙΚΟΤΗΤΑ

Γλώσσα Προγραμματισμού C++ Εισαγωγή - Μια πρώτη ματιά

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language)

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language) Ιστοσελίδα του µαθήµατος. Περιεχόµενα. ηµήτριος Κατσαρός, Ph.D. Πίνακες.

public void printstatement() { System.out.println("Employee: " + name + " with salary: " + salary);

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Εξαιρέσεις

2.1 Αντικειµενοστρεφής προγραµµατισµός

Κεφάλαιο , 3.2: Συναρτήσεις II. ( ιάλεξη 12) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Abstract classes, Interfaces ΦΡΟΝΤΙΣΤΗΡΙΟ JAVA

Εισαγωγή στον Προγραµµατισµό, Αντώνιος Συµβώνης, ΣΕΜΦΕ, ΕΜΠ,, Slide 6

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

Abstract classes, Interfaces ΦΡΟΝΤΙΣΤΗΡΙΟ JAVA

Εξαιρέσεις. try, catch, finally, throw, throws

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κληρονομικότητα Downcasting Πολυμορφισμός Late Binding

a = 10; a = k; int a,b,c; a = b = c = 10;

Αντικειµενοστρεφής Προγραµµατισµός

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Κεφάλαιο 8 : H γλώσσα προγραµµατισµού Pascal

2 Ορισμός Κλάσεων. Παράδειγμα: Μηχανή για Εισιτήρια. Δομή μιας Κλάσης. Ο Σκελετός της Κλάσης για τη Μηχανή. Ορισμός Πεδίων 4/3/2008

Αναφορές, είκτες και Αλφαριθμητικά

Οντοκεντρικός Προγραμματισμός

ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Αντικειμενοστρεφής Προγραμματισμός

12. ΑΛΦΑΡΙΘΜΗΤΙΚΑ. υο είδη αλφαριθµητικών Τα αλφαριθµητικά της C πίνακες τύπου char Ta αντικείµενα της κλάσης string

Πληροφορική 2. Γλώσσες Προγραμματισμού

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Constructors, equals, tostring

- Το πρόγραµµα σας δίνει τα αναµενόµενα αποτελέσµατα.

1 ΕΙΣΑΓΩΓΗ. Πρωταρχικοί Τύποι

ΜΑΘΗΜΑ: Αντικειμενοστρεφής Προγραμματισμός

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Αναφορές

Υπερφόρτωση (Overloading) Υπέρβαση (Overriding) - Upcasting Downcasting Final classes, methods

Δομές Δεδομένων & Αλγόριθμοι

ΕΞΕΤΑΣΤΕΑ ΥΛΗ (SYLLABUS) ADVANCED αντικειμενοστραφής προγραμματισμός ΕΚΔΟΣΗ 1.0. Σόλωνος 108,Τηλ Φαξ

Πρόγραµµα 9.1 Πέρασµα δεδοµένων στην µνήµη

Εισαγωγή στον Προγραμματισμό

Αντικειμενοστραφής Προγραμματισμός

Λογισµικό (Software SW) Γλώσσες

Εαρινό. Ύλη εργαστηρίου, Ασκήσεις Java

ΚΑΤΑΣΚΕΥΑΣΤΕΣ ΑΝΤΙΓΡΑΦΗΣ

if(συνθήκη) {... // οµάδα εντολών } C: Από τη Θεωρία στην Εφαρµογή 5 ο Κεφάλαιο

Επισκόπηση. Κατανεµηµένα Συστήµατα Ι Μάθηµα Βασικής Επιλογής, Χειµερινού Εξαµήνου Τοµέας Εφαρµογών και Θεµελιώσεων. Λεπτοµέρειες υλοποίησης αλγορίθµων

Επισκόπηση. Κατανεµηµένα Συστήµατα Ι Μάθηµα Βασικής Επιλογής, Χειµερινού Εξαµήνου Τοµέας Εφαρµογών και Θεµελιώσεων. Simulation Commands

Σε γενικές γραμμές, είναι καλή πρακτική να γράϕουμε προγράμματα C που αποτελούνται από πολλές και μικρές συναρτήσεις, παρά από λίγες και μεγάλες.

Ερωτήσεις και απαντήσεις στα θέματα του κανονισμού κατάρτισης

Στοίβες - Ουρές. Στοίβα (stack) Γιάννης Θεοδωρίδης, Νίκος Πελέκης, Άγγελος Πικράκης Τµήµα Πληροφορικής

Wrapper Classes, Abstract Classes and Interfaces

Ειδικά Θέματα Προγραμματισμού

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα με πίνακες. Constructors. Υλοποίηση Στοίβας

Τελικό τεστ - απαντήσεις

Οντοκεντρικός Προγραμματισμός ΦΡΟΝΤΙΣΤΗΡΙΟ JAVA

02 Αντικειμενοστρεφής Προγραμματισμός

Εξαιρέσεις Εισαγωγή. Εξαιρέσεις. ηµήτρης Λεβεντέας

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

ΕΞΑΙΡΕΣΕΙΣ. Εξαιρέσεις προκαλούνται. από το σύστηµα. από το πρόγραµµα

ΕισαγωγήστουςΗ/Υ. PHP Hypertext Preprocessor

ΚΑΛΟΥΠΩΜΑΤΑ & ΜΕΤΑΤΡΟΠΕΣ

Ενδεικτική περιγραφή μαθήματος

Transcript:

1 Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language) ηµήτριος Κατσαρός, Ph.D. Χειµώνας 2005 ιάλεξη 10η

2 Ιστοσελίδα του µαθήµατος http://skyblue.csd.auth.gr/~dimitris/courses/cpp_fall05.htm Θα τοποθετούνται οι διαφάνειες του επόµενου µαθήµατος Επικοινωνία: dimitris@skyblue.csd.auth.gr

3 Περιεχόµενα Πολυµορφισµός & Εικονικές συναρτήσεις (Polymorphism & Virtual functions) ιαχείριση εξαιρέσεων (Exception Handling)

4 Στόχοι εκµάθησης Τα βασικά των εικονικών συναρτήσεων Καθυστερηµένη σύνδεση (late binding) Υλοποίηση εικονικών συναρτήσεων Πότε χρησιµοποιούµε εικονικές συναρτήσεις Abstract κλάσεις και καθαρά εικονικές συναρτήσεις είκτες και εικονικές συναρτήσεις Συµβατότητα εκτεταµένων τύπων Downcasting και upcasting C++ κάτω από το κάλυµµα µε εικονικές συναρτήσεις

5 Βασικά των εικονικών συναρτήσεων Πολυµορφισµός (Polymorphism) Συσχέτιση πολλών εννοιών µε µια ΜΙΑ συνάρτηση Οι εικονικές συναρτήσεις παρέχουν αυτή τη δυνατότητα Θεµελιώδης αρχή του αντικειµενοστραφούς προγραµµατισµού! Εικονικός ή Υπερβατικός (Virtual) Υπάρχει στην ουσία, αλλά όχι στην πράξη Εικονική ή υπερβατική συνάρτηση (virtual function) Μπορεί να χρησιµοποιηθεί πριν οριστεί

6 Παράδειγµα µε Σχήµατα (1/2) Ας το δούµε µέσα από ένα παράδειγµα: Κλάσεις για διάφορα είδη σχηµάτων Ορθογώνια, κύκλοι, ελλείψεις, κ.τ.λ. Κάθε σχήµα είναι ένα αντικείµενο διαφορετικής κλάσης εδοµένα ορθογωνίου: height, width, center point εδοµένα κύκλου: center point, radius Όλες παράγονται από µια βασική κλάση: Figure Απαιτούν τη συνάρτηση: draw() ιαφορετικές εντολές σχεδίασης για κάθε σχήµα

7 Παράδειγµα µε Σχήµατα (2/2) Κάθε κλάση χρειάζεται διαφορετική συνάρτηση draw Μπορούµε να την ονοµάσουµε "draw" σε κάθε κλάση, έτσι: Rectangle r; Circle c; r.draw(); //Καλεί τη draw της κλάσης Rectangle c.draw(); // Καλεί τη draw της κλάσης Circle Μέχρι στιγµής δεν παρουσιάστηκε κάτι διαφορετικό από αυτά που γνωρίζουµε

8 Παράδειγµα µε Σχήµατα: center() Η γονική κλάση Figure περιέχει συναρτήσεις που εφαρµόζονται σε όλα τα figures; Θεωρήστε τη: center(): µετακινεί ένα figure στο κέντρο της οθόνης ιαγράφει το πρώτο, κατόπιν το ξανασχεδιάζει Έτσι η Figure::center() θα χρησιµοποιούσε τη συνάρτηση draw() για να ξανασχεδιάσει Επιπλοκές! Ποια συνάρτηση draw()? Ποιας κλάσης?

9 Παράδειγµα µε Σχήµατα: νέο Figure Θεωρήστε ότι ένα νέο είδος figure εµφανίζεται: Triangle class που παράγεται από την κλάση Figure Η συνάρτηση center() κληρονοµείται από την κλάση Figure Θα δουλέψει για τα triangles? Χρησιµοποιεί τη draw(), η οποία είναι διαφορετική για κάθε figure! Εάν χρησιµοποιήσει τη Figure::draw() δεν θα δουλέψει για τα triangles Θέλουµε η κληρονοµούµενη συνάρτηση center() να χρησιµοποιήσει τη συνάρτηση Triangle::draw() ΌΧΙ τη συνάρτηση Figure::draw() Αλλά η κλάση Triangle ΕΝ ΕΙΧΕ ΓΡΑΦΤΕΙ όταν γράφτηκε η Figure::center()! Η τελευταία δεν γνωρίζει triangles!

10 Παράδειγµα µε Σχήµατα: Virtual! Η απάντηση είναι οι εικονικές συναρτήσεις Λένε στον compiler: εν γνωρίζω πώς υλοποιείται η συνάρτηση Περίµενε µέχρι να χρησιµοποιηθεί στο πρόγραµµα Τότε, πάρε την υλοποίηση από το αντικείµενο όπου ανήκει Αποκαλείται καθυστερηµένη σύνδεση (late binding) ή δυναµική σύνδεση (dynamic binding) Οι εικονικές συναρτήσεις υλοποιούν τον µηχανισµό του late binding

Εικονικές συναρτήσεις: άλλο 11 παράδειγµα Πρόγραµµα record-keeping για κατάστηµα ανταλλακτικών αυτοκινήτων Κρατά τις πωλήσεις (sales) εν γνωρίζει ακόµα όλες τις πωλήσεις Πρώτα: µόνο τις τακτικές retail πωλήσεις Αργότερα: Discount sales, mail-order, κ.τ.λ. Εξαρτάται και από άλλους παράγοντες εκτός από την τιµή, φόρο

12 Εικονικές συναρτήσεις: ανταλλακτικά Το πρόγραµµα πρέπει: Να υπολογίζει τις καθηµερινές µεικτές πωλήσεις Υπολογίζει µεγαλύτερη/µικρότερη πώληση της ηµέρας Ίσως µέση πώληση ανά µέρα Όλα προέρχονται από επιµέρους λογαριασµούς Αλλά πολλές συναρτήσεις για υπολογισµό λογαριασµών θα προστεθούν αργότερα! Όταν προστεθούν διαφορετικοί τύποι πωλήσεων! Έτσι, η συνάρτηση που θα υπολογίζει ένα λογαριασµό θα είναι εικονική!

13 Ορισµός κλάσης Sale class Sale { public: Sale(); Sale( double theprice ); double getprice( void ) const; virtual double bill( void ) const; double savings( const Sale& other ) const; }; private: double price;

14 Μέλη: savings και τελεστής < double Sale::savings(const Sale& other) const { return (bill() other.bill()); } bool operator <(const Sale& first, const Sale& second) { return (first.bill() < second.bill()); } Παρατηρήστε ότι ΚΑΙ ΟΙ ΥΟ χρησιµοποιούν τη συνάρτηση-µέλος bill()!

15 Κλάση Sale Αναπαριστά πωλήσεις ενός αντικειµένου χωρίς επιπρόσθετες εκπτώσεις ή επιβαρύνσεις Παρατηρήστε τη δεσµευµένη λέξη "virtual" στη δήλωση της συνάρτησης-µέλος bill Επίδραση: αργότερα, οι παραγόµενες από τη Sale κλάσεις µπορούν να ορίσουν τις ΙΚΕΣ ΤΟΥΣ εκδόσεις της συνάρτησης bill Οι άλλες συναρτήσεις-µέλη της Sale θα χρησιµοποιήσουν εκείνη την έκδοση της bill, ανάλογα µε το αντικείµενο της παραγόµενης κλάσης! εν θα χρησιµοποιήσουν αυτόµατα την έκδοση της κλάσης Sale!

Ορισµός παραγόµενης κλάσης 16 DiscountSale class DiscountSale : public Sale { public: DiscountSale(); DiscountSale(double theprice,double thediscount); double getdiscount( void ) const; void setdiscount( double newdiscount ); double bill( void ) const; }; private: double discount;

Υλοποίηση της συνάρτησης bill() 17 της κλάσης DiscountSale (1/2) double DiscountSale::bill( void ) const { double fraction = discount/100; return (1 fraction)*getprice(); } Ο προσδιοριστής "virtual" δεν µπαίνει στην υλοποίηση της συνάρτησης Γίνεται αυτόµατα εικονική και στην παραγόµενη κλάση Ούτε η δήλωση (στο interface) απαιτείται να έχει τη λέξη "virtual" (αλλά συνήθως τη βάζουµε)

Υλοποίηση της συνάρτησης bill() 18 της κλάσης DiscountSale (2/2) Εικονική συνάρτηση σε βασική κλάση: Γίνεται αυτόµατα εικονική στην παραγόµενη κλάση Στη δήλωση της παραγόµενης κλάσης (στο interface) εν χρειάζεται να υπάρχει η δεσµευµένη λέξη "virtual" Αλλά συνήθως τη βάζουµε, για να διευκολύνουµε την αναγνωσιµότητα

19 Η παραγόµενη κλάση DiscountSale Στην κλάση DiscountSale, η συνάρτηση-µέλος bill() υλοποιείται διαφορετικά από ότι στην κλάση Sale Εξειδικευµένα για "discounts" Οι συναρτήσεις-µέλη savings και "<" Θα χρησιµοποιήσουν αυτό τον ορισµό της bill() για όλα τα αντικείµενα της κλάσης DiscountSale! Αντί να χρησιµοποιήσουν την εξ ορισµού έκδοση που υπάρχει στην κλάση Sales!

20 Virtual: Ισχυρός µηχανισµός! Θυµηθείτε ότι η κλάση Sale γράφτηκε πολύ πριν την παραγόµενη κλάση DiscountSale Οι συναρτήσεις-µέλη savings και "<" µεταγλωττίστηκαν πριν ακόµα συλλάβουµε την ιδέα της κλάσης DiscountSale Πάραυτα, µια κλήση όπως η: DiscountSale d1, d2; d1.savings(d2); Στην savings() η κλήση στην bill() γνωρίζει ότι πρέπει να χρησιµοποιήσει τον ορισµό της bill() που υπάρχει στην κλάση DiscountSale Ισχύς!

21 Virtual: Πώς? Η συγγραφή C++ προγραµµάτων: Υποθέτουµε ότι γίνεται µε µαγικό τρόπο! Αλλά η εξήγηση αφορά την καθυστερηµένη σύνδεση (late binding) Οι εικονικές συναρτήσεις υλοποιούν τον µηχανισµό του late binding Λένε στον compiler να περιµένει µέχρι η συνάρτηση να χρησιµοποιηθεί στο πρόγραµµα Αποφασίζει ποιον ορισµό να χρησιµοποιήσει µε βάση το καλούν αντικείµενο Πολύ σηµαντική αρχή του OOP!

22 Υπέρβαση (overriding) Ο ορισµός µιας εικονικής συνάρτησης αλλάζει σε µια παραγόµενη κλάση Λέµε ότι έχει γίνει υπέρβασή της Παρόµοιο µε τον επαν-ορισµό Θυµηθείτε: για τις τυπικές συναρτήσεις Έτσι: Αλλαγή εικονικών συναρτήσεων: overridden Αλλαγή µη-εικονικών συναρτήσεων: redefined

Εικονικές συναρτήσεις:γιατί όχι όλες? 23 Καθαρή υπεροχή των εικονικών συναρτήσεων, όπως έχουµε δει Ένα, αλλά σηµαντικό, µειονέκτηµα: overhead! Χρησιµοποιεί περισσότερο αποθηκευτικό χώρο Late binding είναι µια διαδικασία "on the fly", έτσι το πρόγραµµα εκτελείται πιο αργά Έτσι, εάν οι εικονικές συναρτήσεις δεν χρειάζονται πραγµατικά, δεν θα πρέπει να χρησιµοποιούνται

Καθαρά εικονικές συναρτήσεις 24 (pure virtual functions) Στη βασική κλάση, ίσως να µην έχει νόηµα να υπάρχει ορισµός για κάποιες ή όλες από τις συναρτήσεις-µέλη της! Ο σκοπός της είναι απλά για να παράγονται άλλες κλάσεις από αυτή Θυµηθείτε την κλάση Figure Όλα τα figures είναι αντικείµενα παραγόµενων κλάσεων Rectangles, circles, triangles, κ.τ.λ. Η κλάση Figure δεν γνωρίζει πώς να σχεδιάσει (draw)! Την κάνουµε pure virtual function: virtual void draw() = 0;

25 Abstract βασικές κλάσεις Οι pure virtual functions δεν χρειάζονται ορισµό Εξαναγκάζονται όλες οι παραγόµενες κλάσεις να ορίσουν τις δικές τους εκδόσεις των συναρτήσεων Μια κλάση που έχει µια ή περισσότερες pure virtual functions είναι µια: abstract base class Μπορεί να χρησιµοποιηθεί µόνο ως βασική κλάση εν µπορούν να δηµιουργηθούν αντικείµενα από αυτή Αφού δεν έχει πλήρεις ορισµούς όλων των µελών της! Εάν µια παραγόµενη κλάση δεν µπορέσει να ορίσει όλα τα pure που κληρονόµησε, τότε: Είναι και αυτή µια abstract base class

26 Συµβατότητα εκτεταµένων τύπων Έστω ότι: η κλάση Derived παράγεται από τη Base Τα αντικείµενα Derived µπορούν να ανατεθούν σε αντικείµενα τύπου Base Αλλά ΌΧΙ ανάποδα! Θεωρήστε το προηγούµενο παράδειγµα: Ένα DiscountSale Είναι ένα Sale, αλλά το αντίστροφο δεν είναι αληθές

Παράδ. Συµβατότητα εκτεταµένων τύπων class Pet { public: string name; virtual void print() const; }; class Dog : public Pet { public: string breed; virtual void print() const; }; 27

28 Κλάσεις Pet και Dog Έστωσαν τώρα οι δηλώσεις: Dog vdog; Pet vpet; Παρατηρήστε ότι οι µεταβλητές-µέλη name και breed είναι public Για χάρην του παραδείγµατος

29 Χρήση των κλάσεων Pet και Dog Ο,τιδήποτε είναι dog Eίναι ένα pet: vdog.name = "Tiny"; vdog.breed = "Great Dane"; vpet = vdog; Αυτές οι αναθέσεις είναι επιτρεπτές Μπορούµε να αναθέσουµε τιµές σε τύπογονέα, αλλά όχι το αντίστροφο Ένα pet εν είναι ένα dog (όχι αναγκαστικά)

30 Το πρόβληµα Slicing Παρατηρήστε ότι η τιµή που ανατίθεται στο vpet χάνει το πεδίο της breed! cout << vpet.breed; Παράγει ERROR µήνυµα! Αποκαλείται Πρόβληµα Slicing Ίσως φαίνεται αποδεκτό Το dog µετακινήθηκε στη µεταβλητή Pet, και συνεπώς θα έπρεπε να αντιµετωπίζεται ως ένα Pet Και εποµένως δεν θα πρέπει να έχει τις ιδιότητες ενός "dog" Προκαλεί ενδιαφέρουσα φιλοσοφική συζήτηση

31 ιορθώνοντας το Πρόβληµα Slicing Στη C++, το πρόβληµα slicing είναι µπελάς Θα θέλαµε να αναφερόµαστε στο πεδίο breed, παρόλο που αντιµετωπίζεται ως ένα Pet Μπορούµε να το κάνουµε αυτό µε τους δείκτες σε δυναµικές µεταβλητές

32 Παράδειγµα προβλήµατος Slicing Pet *ppet; Dog *pdog; pdog = new Dog; pdog->name = "Tiny"; pdog->breed = "Great Dane"; ppet = pdog; εν µπορούµε να προσπελάσουµε το πεδίο breed του αντικειµένου που δείχνεται από τον δείκτη ppet: cout << ppet->breed; //ILLEGAL!

33 Παράδειγµα προβλήµατος Slicing Πρέπει να χρησιµοποιήσουµε την εικονική συνάρτηση-µέλος: ppet->print(); Καλεί την συνάρτηση-µέλος print της κλάσης Dog! Επειδή είναι virtual Η C++ περιµένει να δει σε τι είδους αντικείµενο δείχνει ο δείκτης ppet πριν κάνει τη σύνδεση µε µια συγκεκριµένη κλήση συνάρτησης

34 Εικονικοί Destructors Θυµηθείτε: οι destructors πρέπει να αποδεσµεύσουν τη δυναµικά δεσµευµένη µνήµη Θεωρήστε τη δήλωση: Base *pbase = new Derived; delete pbase; Θα καλέσει τον destructor της βασικής κλάσης παρόλο που δείχνει σε αντικείµενο κλάσης Derived! Εάν κάνουµε τον destructor virtual τότε λύνουµε το πρόβληµα! Καλή πολιτική για όλους τους destructors να είναι εικονικοί

35 Προσαρµογή (casting) Θεωρήστε το: Pet vpet; Dog vdog; vdog = static_cast<dog>(vpet); //ILLEGAL! εν µπορούµε να κάνουµε cast ένα pet ώστε να γίνει ένα dog, αλλά: vpet = vdog; // Legal! vpet = static_cast<pet>(vdog); //Also legal! Το upcasting είναι OK Από τύπο-απογόνου σε τύπο-προγόνου

36 Downcasting Το downcasting είναι επικίνδυνο! Κάνοντας casting από τύπο προγόνου σε τύπο απογόνου Υποθέτει ότι προστίθεται πληροφορία Μπορεί να γίνει µε dynamic_cast: Pet *ppet; ppet = new Dog; Dog *pdog = dynamic_cast<dog*>(ppet); Έγκυρο, αλλά επικίνδυνο! Σπάνια εφαρµόζουµε downcasting εξαιτίας των παγίδων Πρέπει να προσέχουµε την πληροφορία που προστίθεται Όλες οι συναρτήσεις-µέλη πρέπει να είναι εικονικές

Εσωτερική λειτουργία των 37 Εικονικών Συναρτήσεων Χρειάζεται απλώς να ξέρουµε πώς να τις χρησιµοποιήσουµε! Αρχή της Απόκρυψης Πληροφορίας Πίνακας Εικονικών Συναρτήσεων (Virtual function table) Τον δηµιουργεί ο compiler Έχει δείκτες για κάθε εικονική συνάρτηση-µέλος είχνει στη θέση του σωστού κώδικα για τη συνάρτηση αυτή Τα αντικείµενα αυτών των κλάσεων έχουν επίσης ένα δείκτη είχνει στον Πίνακα Εικονικών Συναρτήσεων

38 Περίληψη 1 Η καθυστερηµένη σύνδεση αναβάλλει την απόφαση για το ποια συνάρτηση-µέλος θα κληθεί µέχρι την εκτέλεση του προγράµµατος Στη C++, οι εικονικές συναρτήσεις χρησιµοποιούν καθυστερηµένη σύνδεση Οι καθαρά εικονικές συναρτήσεις δεν έχουν ορισµό Οι κλάσεις µε µια τουλάχιστον εικονική συνάρτηση είναι/λέγονται abstract εν µπορούµε να δηµιουργήσουµε αντικείµενα µιας abstract κλάσης Χρησιµοποιούνται µόνο ως βασική κλάση για να παραχθούν άλλες

39 Περίληψη 2 Αντικείµενα µιας παραγόµενες κλάσης µπορούν να ανατεθούν σε αντικείµενα µιας βασικής τους κλάσης Τα χαρακτηριστικά της παραγόµενης κλάσης χάνονται; Πρόβληµα slicing Ανάθεση δεικτών και δυναµικά αντικείµενα Επιτρέπουν διόρθωση του προβλήµατος slicing Κάνουµε όλους τους destructors εικονικούς Καλή προγραµµατιστική τακτική Εγγυάται σωστή αποδέσµευση της µνήµης

40 Περιεχόµενα Πολυµορφισµός & Εικονικές συναρτήσεις (Polymorphism & Virtual functions) ιαχείριση εξαιρέσεων (Exception Handling)

41 Στόχοι εκµάθησης Τα βασικά της ιαχείρισης Εξαιρέσεων (exception handling) Ορίζοντας κλάσεις εξαιρέσεων Πολλαπλά throws και catches Καθορισµοί για exception Τεχνικές προγραµµατισµού για ιαχείριση Εξαιρέσεων Πότε να στέλνουµε exceptions Ιεραρχίες κλάσεων Exceptions

42 Εισαγωγικά Τυπική προσέγγιση στην ανάπτυξη: Γράφουµε προγράµµατα υποθέτοντας ότι τα πράγµατα θα πάνε όπως τα σχεδιάσαµε Φτιάχνουµε τον πυρήνα της λειτουργικότητας Κατόπιν, λαµβάνουµε µέριµνα για εξαιρετικές περιπτώσεις Λειτουργίες exception-handling στη C++ Χειρισµός εξαιρετικών καταστάσεων Μηχανισµός σηµατοδοτεί ασυνήθη κατάσταση Άλλο µέρος του κώδικα χειρίζεται την exception

43 Τα βασικά του exception-handling Υπονοείται ότι πρέπει να χρησιµοποιούνται σπάνια Σε ειδικές περιπτώσεις ύσκολα διδάσκονται τόσο µεγάλα παραδείγµατα Προσέγγιση: Απλά παιδικά παραδείγµατα, στα οποία φυσιολογικά δεν θα χρησιµοποιούνταν exception-handling Να έχουµε στο µυαλό µας τη µεγάλη εικόνα

44 Απλό παράδειγµα Φανταστείτε: σπάνια ξεµένουµε από γάλα: cout << "Enter number of donuts:"; cin >> donuts; cout << "Enter number of glasses of milk:"; cin >> milk dpg = donuts/static_cast<double>(milk); cout << donuts << "donuts.\n"; << milk << "glasses of milk.\n"; << "You have " << dpg << "donuts for each glass of milk.\n"; Ο βασικός κώδικας υποθέτει ότι δεν θα ξεµείνουµε από γάλα

45 Απλό παράδειγµα if-else Παρατηρήστε: Εάν τελειώσει το γάλα διαίρεση µετοµηδέν! Το πρόγραµµα θα πρέπει να λαµβάνει µέριµνα για την περίπτωση που ξεµείνουµε από γάλα Μπορούµε απλά να χρησιµοποιήσουµε τη δοµή if-else: if (milk <= 0) cout << "Go buy some milk!\n"; else { } Παρατηρήστε: όχι exception-handling εδώ

46 Παράδειγµα Exception Handling

47 Συζήτηση του παραδείγµατος Κώδικας µεταξύ των δεσµευµένων λέξεων try και catch Ίδιος κώδικας όπως και στην κανονική έκδοση, εκτός από το ότι η δήλωση if είναι απλούστερη: if( milk <= 0 ) throw donuts; Καθαρότερος κώδικας Εάν "no milk" κάνε κάτι κατ εξαίρεση Αυτό το κάτι κατ εξαίρεση παρέχεται µετά από τη δεσµευµένη λέξη catch

48 Συζήτηση του παραδείγµατος Το µπλοκ try Χειρίζεται την κανονική κατάσταση Το µπλοκ catch Χειρίζεται την κατ εξαίρεση κατάσταση Παρέχει διαχωρισµό του κανονικού από τον κατ εξαίρεση κώδικα Βέβαια για το απλό αυτό παράδειγµα δεν είναι κάτι σπουδαίο, αλλά στη γενική περίπτωση είναι σηµαντικός µηχανισµός

49 Το µπλοκ try Η βασική µέθοδος της διαχείρισης εξαιρέσεων είναι το try-throw-catch Το µπλοκ try: try { Some_Code; } Περιέχει τον κώδικα για τον βασικό αλγόριθµο, όταν όλα πηγαίνουν καλά

50 throw Μέσα στο µπλοκ try, όταν συµβεί κάτι ασυνήθιστο: try { Code_To_Try if (exceptional_happened) throw donuts; More_Code } Η δεσµευµένη λέξη throw ακολουθείται από τον τύπο της εξαίρεσης Αποκαλείται "throwing an exception"

51 Το µπλοκ catch Όταν κάτι is thrown πηγαίνει κάπου Στη C++, η ροή του ελέγχου πηγαίνει από το try-block στο catch-block Έξοδος από το try-block και ο έλεγχος µεταφέρεται στο catch-block Η εκτέλεση του catch block αποκαλείται called "catching the exception" Η διαχείριση των εξαιρέσεωνς πρέπει να γίνεται σε κάποιο catch block

52 Περισσότερα για το catch-block Θυµηθείτε: catch( int e ) { cout << e << " donuts, and no milk!\n"; << " Go buy some milk.\n"; } Μοιάζει µε ορισµό συνάρτησης µε παράµετρο int! εν είναι συνάρτηση, αλλά λειτουργεί παρόµοια Το throw είναι όπως η κλήση συνάρτησης

53 Η παράµετρος στο catch-block Θυµηθείτε: catch(int e) Το "e" αποκαλείται παράµετρος του catch-block Κάθε catch block µπορεί να έχει ΤΟ ΠΟΛΥ µια παράµετρο Κάνει δυο πράγµατα: 1. Το όνοµα του τύπου καθορίζει τo είδος που µπορεί να πιάσει το catch-block 2. Παρέχει ένα όνοµα για την τιµή που συλλαµβάνειται, ώστε να µπορούµε να κάνουµε διάφορα πράγµατα µε την τιµή αυτή

54 Ορίζοντας κλάσεις από exceptions Η δήλωση throw µπορεί να πετάξει τιµές οποιουδήποτε τύπου Κλάση exception Περιέχει αντικείµενα µε πληροφορία που is thrown Μπορεί να έχει διαφορετικούς τύπους αναγνωρίζοντας κάθε πιθανή κατάσταση εξαίρεσης Παρόλ αυτά είναι µια κλάση Ονοµάζεται "exception class" εξαιτίας του πώς χρησιµοποιείται

55 Παράδειγµα κλάσης Exception Θεωρήστε το: class NoMilk { public: NoMilk() { } NoMilk( int howmany ) : count( howmany ) { } int getcount() const { return count; } private: int count; }; throw NoMilk(donuts); Ενεργοποεί τον constructor της κλάσης of NoMilk

56 Πολλαπλά throws και catches Το try-block τυπικά µπορεί να πετάξει οποιοδήποτε αριθµό exceptions, διαφορετικών τύπων Φυσικά, πετάει µόνο µια κάθε φορά Αφού η δήλωση throw τερµατίζει το try-block Αλλά διαφορετικοί τύποι µπορεί να πεταχτούν Κάθε catch block πιάνει µόνο έναν τύπο Είναι σύνηθες να τοποθετούµε πολλά catch-blocks µετά από κάθε try-block Για να πιάσουµε όλες τις πιθανές exceptions που µπορεί να πεταχτούν

57 Catching Η σειρά των catch blocks είναι σηµαντική Τα catch-blocks δοκιµάζονται µε τη σειρά εµφάνισής τους µετά το try-block Το πρώτο ταίριασµα είναι αυτό που χειρίζεται την εξαίρεση! Θεωρήστε το: catch ( ) { } Αποκαλείται "catch-all", "default" exception handler Πιάνει οποιαδήποτε εξαίρεση Βεβαιωθείτε ότι το catch-all τοποθετείται ΜΕΤΑ από τις πιο ειδικές exceptions! Ή οι άλλες δεν θα πιαστούν ποτέ!

58 Τετριµµένη Exception κλάση Θεωρήστε το: class DivideByZero { } εν έχει µεταβλητές-µέλη εν έχει συναρτήσεις-µέλη (εκτός από τον default constructor) Τίποτε άλλο, εκτός από το όνοµά της Όπου δεν χρειάζεται να κάνουµε κάτι µε την τιµή της εξαίρεσης Χρησιµοποιείται απλά για να πιάνεται στο catch block Μπορούµε να παραλείπουµε την παράµετρο του catch block

59 Throwing exception από συνάρτηση Μια συνάρτηση µπορεί να πετάξει µια exception Οι καλούντες µπορεί να έχουν διαφορετικές αντιδράσεις Μερικές µπορεί να επιθυµούν τερµατισµό του προγράµµατος Μερικές µπορεί να συνεχίζουν, ή να κάνουν κάτι άλλο Είναι λογικό να πιάνουµε µια exception στην καλούσα συνάρτηση Τοποθετούµε τον κώδικα µέσα σε try-block Χειριζόµαστε την exception στο catch-block µετά το try-block

Παράδειγ. exception από συνάρτηση Θεωρήστε το: try { quotient = safedivide(num, den); } catch (DivideByZero) { } Η συνάρτηση safedivide() πετάει µια exception DividebyZero Την οποία χειρίζεται το catch-block της καλούσας συνάρτησης 60

61 Καθορισµός των exception Οι συναρτήσεις που δεν πιάνουν exceptions Θα πρέπει να προειδοποιούν τους χρήστες τους ότι θα µπορούσαν να πετάξουν µια exception Αλλά δεν την πιάνουν οι ίδιες! Θα πρέπει να απαριθµούµε αυτές τις exceptions: double safedivide(int top, int bottom) throw (DividebyZero); Αποκαλείται "exception specification" ή "throw list" Θα πρέπει να εµφανίζεται στη δήλωση και στον ορισµό Εάν δεν υπάρχει throw list όλοι οι τύποι

62 Λίστα των throw Εάν µια συνάρτηση πετάξει µια exception την οποία δεν καθορίζει στη λίστα των throws: εν υπάρχει λάθος (compile ή run-time) Καλείται αυτόµατα η συνάρτηση unexpected() Εξ ορισµού συµπεριφορά είναι το τερµατισµός Μπορούµε να τροποποιήσουµε τη συµπεριφορά Το ίδιο αποτέλεσµα εάν δεν βρεθεί catchblock

63 Περίληψη της λίστας των throw void somefunction() throw(dividebyzero, OtherException); //Exception types DividebyZero or OtherException //treated normally. All others invoke unexpected() void somefunction() throw (); //Empty exception list, all exceptions invoke //unexpected() void somefunction(); //All exceptions of all types treated normally

64 Παραγόµενες κλάσεις Θυµηθείτε: τα αντικείµενα µιας παραγόµενης κλάσης είναι επίσης αντικείµενα της βασικής κλάσης Θεωρήστε το: η κλάση D παράγεται από την κλάση B Εάν η B είναι στη λίστα των throws Αντικείµενα της κλάσης D που πετάγονται ως exceptions, θα αντιµετωπίζονται κανονικά, αφού είναι επίσης αντικείµενα της κλάσης B Σηµειώστε: δεν γίνεται αυτόµατο type casting: Το να πεταχτεί double δεν είναι το ίδιο µε το να πεταχτεί ένας int

65 Η συνάρτηση unexpected() Εξ ορισµού ενέργεια: τερµατισµός του προγράµµατος εν χρειάζονται ειδικά includes ή directives using Συνήθως δεν χρειάζεται να την ξαναορίσουµε Αλλά, έχουµε αυτή τη δυνατότητα: Χρησιµοποιούµε τη set_unexpected() Οι λεπτοµέρειες είναι πέρα από το αντικείµενο αυτού του µαθήµατος

66 Πότε πετάµε exceptions Σύνηθες να διαχωρίζουµε throws και catches Σε διαφορετικές συναρτήσεις Throwing συνάρτηση: Απαριθµήστε τις exceptions στην λίστα των throws Στη δήλωση και στον ορισµό Catching συνάρτηση: ιαφορετική συνάρτηση, ίσως σε διαφορετικό αρχείο

67 Προτιµώµενη throw-catch: throw void functiona() throw (MyException) { throw MyException(arg); } Η συνάρτηση πετάει exception όπως δήλωσε

68 Προτιµώµενη throw-catch: catch Τότε κάποια άλλη συνάρτηση: void functionb( void ) { try { functiona(); } catch( MyException e ) { // Handle exception } }

69 Exceptions που δεν πιάστηκαν Πρέπει να πιάνουµε κάθε exception Εάν όχι το πρόγραµµα τερµατίζεται Καλείται η συνάρτηση terminate() Θυµηθείτε για τις συναρτήσεις Εάν η exception δεν υπάρχει στην λίστα των throw: καλείται η unexpected() Με τη σειρά της καλεί την terminate() Έτσι, έχουµε το ίδιο αποτέλεσµα

70 Κατάχρηση των exceptions Οι exceptions αλλάζουν τη ροή του ελέγχου Χάνεται ο έλεγχος της ροής Θα πρέπει να χρησιµοποιούνται µε µέτρο Καλός κανόνας: Εάν επιθυµούµε µια "throw": εξετάστε το ενδεχόµενο να γράψετε τον κώδικα χωρίς αυτή Εάν υπάρχει εναλλακτική ακολουθήστε τη

71 Ιεραρχίες κλάσεων exceptions Είναι χρήσιµες; Θεωρήστε το: Η κλάση DivideByZero παράγεται από τη: κλάση exception ArithmeticError Όλα τα catch-blocks για την ArithmeticError θα πιάσουν και την DivideByZero Εάν η ArithmeticError είναι δηλωµένη στην λίστα των throws, τότε η DividebyZero θα εξεταστεί εκεί

72 Έλεγχος διαθέσιµης µνήµης Ο τελεστής new πετάει exception bad_alloc εάν δεν υπάρχει αρκετή µνήµη: try { NodePtr pointer = new Node; } catch (bad_alloc) { cout << "Ran out of memory!"; // Can do other things here as well } Στη βιβλιοθήκη <new>, και namespace std

73 Ξαναπετώντας µια exception Είναι έγκυρο να πετάει ο κώδικας µια exception ΜΕΣΑ σε ένα catch-block! Μόνο σε σπάνιες περιπτώσεις Την πετάει σε κάποιο catch-block υψηλότερα στην αλυσίδα εκτέλεσης Μπορούµε να ξαναπετάξουµε την ίδια ή νέα exception rethrow; Throws same exception again throw newexceptionup; Throws new exception to next catch-block