User Tools

Site Tools


cpp:exception

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
cpp:exception [2018/05/21 05:55] – [Διαχείριση Εξαιρέσεων] gthanoscpp:exception [2019/05/06 07:13] – [Διαχείριση Εξαιρέσεων] gthanos
Line 1: Line 1:
 ====== Διαχείριση Εξαιρέσεων ====== ====== Διαχείριση Εξαιρέσεων ======
  
-Ας εξετάσουμε την κλάση **Vector** που είδαμε στην υπερφόρτωση των τελεστών. Ο προσδιοριστής //nothrow// σε συνδυασμό με τον τελεστή **new** μας υποχρεώνει να ελέγξουμε την επιστρεφόμενη τιμή του τελεστή **new** για να δούμε έαν έχει αποτύχει η διαδικασία δέσμευσης μνήμης ή όχι και στην περίπτωση που έχουμε αποτυχία τερματίζουμε το πρόγραμμα. +Ας εξετάσουμε την κλάση **Vector** που είδαμε στην ενότητα της υπερφόρτωση τελεστών. Ο προσδιοριστής //nothrow// σε συνδυασμό με τον τελεστή **new** μας υποχρεώνει να ελέγξουμε την επιστρεφόμενη τιμή του τελεστή **new** για να δούμε έαν έχει αποτύχει η διαδικασία δέσμευσης μνήμης ή όχι και στην περίπτωση που έχουμε αποτυχία τερματίζουμε το πρόγραμμα. 
  
 <code cpp Vector.cpp> <code cpp Vector.cpp>
Line 43: Line 43:
 </code> </code>
  
-Αν και η παραπάνω διαδικασία δεν είναι λανθασμένη, έχει το βασικό μειονέκτημα ότι θα πρέπει να τερματίσουμε το πρόγραμμα, ακόμη και εάν ο λόγος αποτυχίας είναι ότι ο χρήστης της κλάσης επέτρεψε το πέρασμα αρνητικής τιμής ως όρισμα στον κατασκευαστή.+Αν και η παραπάνω διαδικασία δεν είναι λανθασμένη, έχει το βασικό μειονέκτημα ότι θα πρέπει να τερματίσουμε το πρόγραμμα, ακόμη και εάν ο λόγος αποτυχίας είναι ότι ο χρήστης της κλάσης επέτρεψε το πέρασμα αρνητικής τιμής ως όρισμα στον κατασκευαστή. Ο λόγος είναι ότι στην περίπτωση που αποτύχει η δέσμευση της μνήμης, λόγω λανθασμένου ορίσματος, ο κατασκευαστής της κλάσης **Vector** επιστρέφει ένα αντικείμενο το οποίο δεν είναι σωστά αρχικοποιημένο.
  
 <code cpp VectorUse.cpp> <code cpp VectorUse.cpp>
Line 58: Line 58:
 </code> </code>
  
-Η παραγωγή ενός exception μπορεί να επιλύσει πιο αποτελεσματικά το παραπάνω πρόβλημα διότι επιτρέπει την διαχείριση γεγονότων που δεν επιτρέπουν την ομαλή ροή του προγράμματος. Στο παράδειγμα του κατασκευαστή της κλάσης **Vector**, η αποτυχία κλήσης του τελεστή **new** (χωρίς τον προσδιοριστή //notrhow//) παράγει ένα //exception// τύπου [[http://www.cplusplus.com/reference/new/bad_alloc/|std::bad_alloc]], το οποίο μπορούμε να διαχειριστούμε, όπως παρακάτω:+Η παραγωγή ενός //exception// μπορεί να επιλύσει πιο αποτελεσματικά το παραπάνω πρόβλημαδιότι υποστηρίζει τη διαχείριση συμβάντων που δεν επιτρέπουν την ομαλή εκτέλεση του προγράμματος. Στο παράδειγμα του κατασκευαστή της κλάσης **Vector**, η αποτυχία κλήσης του τελεστή **new** (χωρίς τον προσδιοριστή //notrhow//) παράγει ένα //exception// τύπου [[http://www.cplusplus.com/reference/new/bad_alloc/|std::bad_alloc]], το οποίο μπορούμε να διαχειριστούμε στη μέθοδο //main//, όπως παρακάτω:
  
 <code cpp Vector.cpp> <code cpp Vector.cpp>
Line 117: Line 117:
  
 <WRAP tip 80% center round> <WRAP tip 80% center round>
-Αν και στο παραπάνω απλό παράδειγμα είναι προφανές ότι είναι πιο απλό να ελέγξει κανείς το μέγεθος της παραμέτρου size πριν καλέσει τον κατασκευαστή, κάτι τέτοιο είναι δύσκολο να εφαρμοστεί σε όλες τις περιπτώσεις, όπως για παράδειγμα το μέγεθος **size** παράγεται δυναμικά από το πρόγραμμα και ο κατασκευαστής καλείται σε αρκετά διαφορετικά σημεία του προγράμματος.+Στο παραπάνω απλό παράδειγμα είναι προφανές ότι είναι πιο απλό να ελέγξει κανείς το μέγεθος της παραμέτρου //size// πριν καλέσει τον κατασκευαστή. Σε αυτή την περίπτωση, ο έλεγχος θα πρέπει να γίνεται από το χρήστη της εκάστοτε βιβλιοθήκηςενώ η βιβλιοθήκη δεν παρέχει καμία εγγύηση για τον τρόπο συμπεριφοράς της εάν περαστούν λανθασμένα ορίσματα. Τα //exceptions// εξασφαλίζουν ότι η βιβλιοθήκη θα παράξει μία εξαίρεση εάν η δέσμευση της μνήμης αποτύχει.
 </WRAP> </WRAP>
 ===== Τύποι παραγόμενων εξαιρέσεων ===== ===== Τύποι παραγόμενων εξαιρέσεων =====
Line 338: Line 338:
  
 <WRAP tip 80% center round> <WRAP tip 80% center round>
-Το πιάσιμο μιας εξαίρεσης με χρήση αναφοράς για αντικείμενα σύνθετους τύπου (όχ char, int, long, double κλπ), διότι //α)// αποφεύγουμε την αντιγραφή του αντικειμένου μέσα στο //catch block// (πιο γρήγορος κώδικας) και //β)// αποφεύγουμε την "αποκοπή" μέρους του αντικειμένου που γίνεται //throw// λόγω του ιασίματος" της εξαίρεσης από ένα //catch block// βασικότερου τύπου από τον τύπο που γίνεται //throw//.+Το πιάσιμο μιας εξαίρεσης με χρήση αναφοράς για αντικείμενα σύνθετου τύπου (όχι char, int, long, double κλπ), διότι //α)// αποφεύγουμε την αντιγραφή του αντικειμένου μέσα στο //catch block// (πιο γρήγορος κώδικας) και //β)// αποφεύγουμε την "αποκοπή" μέρους του αντικειμένου της εξαίρεσης λόγω του χειρισμού της από ένα //catch block// βασικότερου τύπου από τον τύπο του αντικειμένου της εξαίρεσης.
 </WRAP> </WRAP>
  
Line 552: Line 552:
       cerr << "std::exception occured!\n";       cerr << "std::exception occured!\n";
       in.close();       in.close();
-      throw ex;       // rethrows the same exception object+      throw;       // rethrows the same exception object
     }     }
 </code> </code>
cpp/exception.txt · Last modified: 2023/05/15 14:01 by gthanos