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/18 14:54] – [Stack Unwinding] gthanoscpp:exception [2018/05/19 06:43] – [Stack Unwinding] gthanos
Line 282: Line 282:
 </code> </code>
  
-Παρατηρήστε ότι ενώ στην 2η περίπτωση παράγεται ένα //DerivedException// το αντικείμενο που τελικά λαμβάνουμε είναι τύπου //BaseException//. Εδώ θα πρέπει να τονίσουμε ότι η συνάρτηση //what()// είναι //virtual// πράγμα που σημαίνει ότι θα πρέπει να καλείται η κατάλληλη συνάρτηση με βάση τον τύπο του αντικειμένου, ανεξάρτητα από τον τύπο της μεταβλητής.+Παρατηρήστε ότι ενώ στην 2η περίπτωση παράγεται ένα //DerivedException// το αντικείμενο που τελικά λαμβάνουμε είναι τύπου //BaseException//. Εδώ θα πρέπει να τονίσουμε ότι η συνάρτηση //what()// είναι //virtual// πράγμα που σημαίνει ότι θα πρέπει να καλείται η κατάλληλη έκδοση της συνάρτησης με βάση τον τύπο του αντικειμένου για το οποίο καλείται, ανεξάρτητα από τον τύπο της η οποία δείχνει στο αντικείμενο (δες [[cpp:polymorphism|δυναμικό πολυμορφισμό]]).
  
-Η απάντηση στο παραπάνω ερώτημα είναι ότι αν και παράγεται ένα αντικείμενο τύπου //DerivedException// αυτό γίνεται //catch// από το πρώτο //catch block//. Μέσα στο //catch block// το αρχικό αντικείμενο αντιγράφεται καθώς έχουμε κλήση με τιμή σε ένα άλλο αντικείμενο τύπου //BaseException//. Πρακτικά αυτό σημαίνει ότι από το αρχικό αντικείμενο κρατάμε οτιδήποτε ανήκει στην κλάση //BaseException// και απορρίπτουμε το υπόλοιπο.+Η απάντηση στο παραπάνω ερώτημα είναι ότι αν και παράγεται ένα αντικείμενο τύπου //DerivedException// αυτό γίνεται //catch// από το πρώτο //catch block//. Μέσα στο //catch block// το αρχικό αντικείμενο αντιγράφεται σε ένα άλλο αντικείμενο τύπου //BaseException//, διότι έχουμε κλήση με τιμή στο //catch block//. Πρακτικά αυτό σημαίνει ότι από το αρχικό αντικείμενο κρατάμε οτιδήποτε ανήκει στην κλάση //BaseException// και απορρίπτουμε το υπόλοιπο.
  
 Ο τρόπος για να δουλέψει σωστά ο παραπάνω κώδικας είναι μέσα στο //catch block// να μην περάσουμε το αντικείμενο γιατί δημιουργείται αντίγραφο, αλλά να περάσουμε μία αναφορά σε αυτό, όπως παρακάτω: Ο τρόπος για να δουλέψει σωστά ο παραπάνω κώδικας είναι μέσα στο //catch block// να μην περάσουμε το αντικείμενο γιατί δημιουργείται αντίγραφο, αλλά να περάσουμε μία αναφορά σε αυτό, όπως παρακάτω:
Line 326: Line 326:
 DerivedException, a: 4, b: 5 DerivedException, a: 4, b: 5
 </code> </code>
 +
 +<WRAP tip 80% center round>
 +Το πιάσιμο μιας εξαίρεσης με χρήση αναφοράς για αντικείμενα σύνθετους τύπου (όχ char, int, long, double κλπ), διότι //α)// αποφεύγουμε την αντιγραφή του αντικειμένου μέσα στο //catch block// (πιο γρήγορος κώδικας) και //β)// αποφεύγουμε την "αποκοπή" μέρους του αντικειμένου που γίνεται //throw// λόγω του "πιασίματος" της εξαίρεσης από ένα //catch block// βασικότερου τύπου από τον τύπο που γίνεται //throw//.
 +</WRAP>
  
 ===== Stack Unwinding ===== ===== Stack Unwinding =====
Line 382: Line 386:
 </code> </code>
  
 +Το αποτέλεσμα που εκτυπώνεται στην οθόνη είναι το εξής:
 +<code>
 +Start main
 +Start F
 +Start FF
 +Start FFF
 +Start FFFF
 +FFFF throwing int literal exception
 +F caught int exception
 +End F
 +End main
 +</code>
 +
 +H εξέλιξη του //program stack// στο παρακάτω πρόγραμμα δίνεται στο παρακάτω διάγραμμα. Παρατηρήστε ότι το exception παράγεται στη συνάρτηση **FFFF()**, αλλά "πιάνεται" στην **F()** πράγμα που συνεπάγεται την αυτόματη συρρίκνωση του //stack// στο επίπεδο της συνάρτησης **F()**. Μετά το "πιάσιμο" του //exception//, τα περιεχόμενα του //stack// για τις συναρτήσεις **FFF()** και **FFFF()** έχουν χαθεί.
  
 +{{ :cpp:stack_unwinding.png |}}
  
  
  
  
cpp/exception.txt · Last modified: 2023/05/15 14:01 by gthanos