User Tools

Site Tools


cpp:function_try_blocks

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:function_try_blocks [2019/05/06 15:16] – [Exception που συμβαίνουν στον κατασκευαστή προγόνου κλάσης] gthanoscpp:function_try_blocks [2019/05/06 19:53] – [Exception που συμβαίνουν στον κατασκευαστή της προγόνου κλάσης] gthanos
Line 1: Line 1:
-====== Εξαιρέσεις στον κατασκευαστή ======+====== Εξαιρέσεις που παράγονται στον κατασκευαστή ======
  
 Ας υποθέσουμε ότι έχουμε την παρακάτω κλάση //Name// η οποία περιγράφει ένα όνομα Ας υποθέσουμε ότι έχουμε την παρακάτω κλάση //Name// η οποία περιγράφει ένα όνομα
  
 <code cpp Name.hpp> <code cpp Name.hpp>
 +#include <cstring>
 +
 class Name { class Name {
   char* name;   char* name;
Line 43: Line 45:
 </code> </code>
  
-Επιπλέον ο κατασκευαστή της κλάση Person παράγει ένα //exception// τύπου BadName. Η κλάσεις BadName και Περσον περιγράφονται παρακάτω:+Επιπλέον ο κατασκευαστή της κλάση Person παράγει ένα //exception// τύπου //BadName//. Η κλάσεις //BadName// και //Person// περιγράφονται παρακάτω:
  
 <code cpp BadName.hpp> <code cpp BadName.hpp>
Line 83: Line 85:
 Εάν μεταγλωττίσουμε και εκτελέσουμε την παρακάτω συνάρτηση //main// ο κώδικας εκτυπώνει τα εξής: Εάν μεταγλωττίσουμε και εκτελέσουμε την παρακάτω συνάρτηση //main// ο κώδικας εκτυπώνει τα εξής:
 <code cpp main.cpp> <code cpp main.cpp>
 +#include <iostream>
 +using namespace std;
 +
 +#include "Person.hpp"
 +
 int main() { int main() {
   try {   try {
Line 102: Line 109:
 </code> </code>
  
-Παρατηρήστε ότι καταστρέφεται το αντικείμενο //lastname//, αλλά όχι και το αντικείμενο //firstname//. Ο λόγος είναι ότι δημιουργηθεί ένα //exception// στον κατασκευαστή, δεν καλείται ποτέ ο καταστροφέας της κλάσης. Ως εκ τούτου, καταστρέφονται αυτόματα όλα τα αντικείμενα που έχουν δεσμευτεί στο //stack//, αλλά όχι τα αντικείμενα που είναι δεσμευσμένα στο //heap// (γενικότερα //resources// που περιμένουμε να απελευθερωθούν στον καταστροφέα).+Από τις εκτυπώσεις, παρατηρούμε ότι καταστρέφεται το αντικείμενο //lastname//, αλλά όχι και το αντικείμενο //firstname//. Ο λόγος είναι ότι δημιουργηθεί ένα //exception// στον κατασκευαστή, __δεν καλείται ποτέ ο καταστροφέας της κλάσης__Καταστρέφονται αυτόματα όλα τα αντικείμενα που έχουν δεσμευτεί στο //stack//, και λαμβάνει χώρα η διαδικασία του //stack unwinding// που είδαμε σε προηγούμενη παράγραφο. 
 + 
 +Ως εκ τούτου, δεν καταστρέφονται τα αντικείμενα που είναι δεσμευμένα στο //heap// και γενικότερα //resources// που περιμένουμε να απελευθερωθούν στον καταστροφέα της κλάσης.
  
 <WRAP tip 80% center round> <WRAP tip 80% center round>
-Ο λόγος που εκτυπώνεται 2 φορές το μήνυμα **"Name destructor: Snow"**, είναι διότι δημιουργούνται δύο αντικείμενα τύπου Name, ένα κατά την αρχικοποίηση του αντικειμένου //Person// και ένα στον κατασκευστή της κλάσης στη γραμμή ''lastname = Name(last);''+Ο λόγος που εκτυπώνεται 2 φορές το μήνυμα **"Name destructor: Snow"**, είναι διότι δημιουργούνται δύο αντικείμενα τύπου Name, ένα κατά την αρχικοποίηση του αντικειμένου //Person// και ένα στον κατασκευαστή της κλάσης στη γραμμή ''lastname = Name(last);''
 </WRAP> </WRAP>
  
 ===== Function Try Blocks ===== ===== Function Try Blocks =====
  
-Προκειμένου να λυθεί το συγκεκριμένο πρόβλημα η //C++// υποστηρίζει τα λεγόμενα //function try blocks//. Ουσιάστικά πρόκειται για μία ειδική σύνταξη //try - catch// που περιλαμβάνει το σύνολο του κατασκευαστή, ως εξής:+Προκειμένου να λυθεί το συγκεκριμένο πρόβλημα η //C++// υποστηρίζει τα λεγόμενα //function try blocks//. Ουσιαστικά πρόκειται για μία ειδική σύνταξη //try - catch// που περιλαμβάνει το σύνολο του κατασκευαστή, ως εξής:
  
 <code cpp > <code cpp >
Line 126: Line 135:
 </code> </code>
  
-Εάν ανανεώσετε τον κώδικα του κατασκευαστή τώρα το πρόγραμμα σας τυπώνει:+Εάν ανανεώσετε τον κώδικα του κατασκευαστή τώρα το πρόγραμμα σας κατά την εκτέλεση εκτυπώνει:
  
 <code> <code>
Line 141: Line 150:
  
 <WRAP tip 80% center round> <WRAP tip 80% center round>
-Παρατηρήστε ότι αν και εκτελείται ο κώδικας μέσα στο //catch block//, η εξαίρεση "μεταφέρεται" και στη συνάρτηση //main///. Ο λόγος είναι ότι υποχρεωτικά η εξαίρεση, παράγεται ξανά στο τέλος του //catch block//. Ο μόνος τρόπος να το αποφύγετε αυτό είναι να κάνετε //throw// μία εξαίρεση διαφορετικού τύπου.+Παρατηρήστε ότι αν και εκτελείται ο κώδικας μέσα στο //catch block//, η εξαίρεση "μεταφέρεται" και στη συνάρτηση //main///. Ο λόγος είναι ότι η εξαίρεση, αναπαράγεται αυτόματα στο τέλος του //catch block//. Ο μόνος τρόπος να το αποφύγετε αυτό είναι να κάνετε //throw// μία νέα εξαίρεσηδιαφορετικού τύπου.
 </WRAP> </WRAP>
  
 ===== Exception που συμβαίνουν στον κατασκευαστή της προγόνου κλάσης ===== ===== Exception που συμβαίνουν στον κατασκευαστή της προγόνου κλάσης =====
  
-Ας υποθέσουμε την κλάση //Student// που είναι απόγοντος της κλάσης //Person// και δηλώνεται ως εξής:+Ας υποθέσουμε την κλάση //Student// που είναι απόγονος της κλάσης //Person// και δηλώνεται ως εξής:
  
 <code cpp Student.hpp> <code cpp Student.hpp>
Line 160: Line 169:
 </code> </code>
  
-Εάν επιθυμούμε να "πιάσουμε" την εξαίρεση εντός του κατασκευαστή της κλάσης //Student// θα πρέπει να την ξαναγράψουμε εξής+Εάν επιθυμούμε να "πιάσουμε" την εξαίρεση εντός του κατασκευαστή της κλάσης //Student// θα πρέπει να κρατήσουμε τον κατασκευαστή της κλάσης //Person// στην αρχική του μορφή και να ξαναγράψουμε τον κατασκευαστή: 
-<code cpp>+ 
 +<code cpp Student.hpp>
 class Student: public Person { class Student: public Person {
   int aem;   int aem;
Line 177: Line 187:
 </code> </code>
  
-Η παραπάνω σύνταξη επιτρέπει να πιάσουμε το exception που συνέβει στον κατασκευαστή της προγόνου κλάσης. Και εδώ το //exception// θα ξανα-παραχθεί σύμφωνά με τους κανόνες που ίσχυσαν και στο προηγούμενο παράδειγμα.+Η παραπάνω σύνταξη επιτρέπει να πιάσουμε το exception που συμβαίνει στον κατασκευαστή της προγόνου κλάσης. Και εδώ το //exception// θα αναπαραχθεί σύμφωνα με τους κανόνες που ίσχυσαν και στο προηγούμενο παράδειγμα. Παρατηρήστε ότι δεν εκτυπώνεται ποτέ το μήνυμα **"Student constructor"** του κατασκευαστή. Γιατί? 
 + 
 +Η μέθοδος //main// για δίνεται παρακάτω: 
 + 
 +<code cpp main.cpp> 
 +#include <iostream> 
 +using namespace std; 
 + 
 +#include "Person.hpp" 
 +#include "Student.hpp" 
 + 
 +int main() { 
 +  try { 
 +    Student johnSnow("John", "Snow", 1234); 
 +  } catch(BadName& a) { 
 +    cout << "Exception occured: " << a.what() << endl; 
 +  } 
 +
 +</code>
  
cpp/function_try_blocks.txt · Last modified: 2022/05/23 06:05 by gthanos