User Tools

Site Tools


cpp:exception_inheritance

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
cpp:exception_inheritance [2019/05/06 08:03] gthanoscpp:exception_inheritance [2023/05/15 14:08] (current) gthanos
Line 6: Line 6:
 using namespace std; using namespace std;
  
-class BaseException: public std::exception {+class BaseException {
 protected: protected:
   int a;   int a;
Line 12: Line 12:
 public: public:
   BaseException(int a) { this->a = a; }   BaseException(int a) { this->a = a; }
-  const char* what() const throw() {+  virtual char* message() {
     sprintf(s, "BaseException, a: %d\n", a);     sprintf(s, "BaseException, a: %d\n", a);
     return s;     return s;
Line 27: Line 27:
 public: public:
   DerivedException(int a, int b): BaseException(a) { this->b = b; }   DerivedException(int a, int b): BaseException(a) { this->b = b; }
-  const char* what() const throw() {+  char* message() {
     sprintf(s, "DerivedException, a: %d, b: %d\n", a, b);     sprintf(s, "DerivedException, a: %d, b: %d\n", a, b);
     return s;     return s;
Line 55: Line 55:
     }     }
   } catch(BaseException ex) {   } catch(BaseException ex) {
-    cout << ex.what();+    cout << ex.message();
   } catch(DerivedException ex) {   } catch(DerivedException ex) {
-    cout << ex.what();+    cout << ex.message();
   }   }
   return 0;   return 0;
Line 85: Line 85:
 </code> </code>
  
-Παρατηρήστε ότι ενώ στην 2η περίπτωση παράγεται ένα //DerivedException// το αντικείμενο που τελικά λαμβάνουμε είναι τύπου //BaseException//. Εδώ θα πρέπει να τονίσουμε ότι η συνάρτηση //what()// είναι //virtual// πράγμα που σημαίνει ότι θα πρέπει να καλείται η κατάλληλη έκδοση της συνάρτησης με βάση τον τύπο του αντικειμένου για το οποίο καλείται, ανεξάρτητα από τον τύπο της η οποία δείχνει στο αντικείμενο (δες [[cpp:polymorphism|δυναμικό πολυμορφισμό]]).+Παρατηρήστε ότι ενώ στην 2η περίπτωση παράγεται ένα //DerivedException// το αντικείμενο που τελικά λαμβάνουμε είναι τύπου //BaseException//. Εδώ θα πρέπει να τονίσουμε ότι η συνάρτηση //message()// είναι //virtual// πράγμα που διαισθητικά μας οδηγεί στο συμπέρασμα ότι θα κληθεί η κατάλληλη έκδοση της συνάρτησης με βάση τον τύπο του αντικειμένου για το οποίο καλείται, ανεξάρτητα από τον τύπο της (δες [[cpp:polymorphism|δυναμικό πολυμορφισμό]]).
  
 Η απάντηση στο παραπάνω ερώτημα είναι ότι αν και παράγεται ένα αντικείμενο τύπου //DerivedException// αυτό γίνεται //catch// από το πρώτο //catch block//. Μέσα στο //catch block// το αρχικό αντικείμενο αντιγράφεται σε ένα άλλο αντικείμενο τύπου //BaseException//, διότι έχουμε κλήση με τιμή στο //catch block//. Πρακτικά αυτό σημαίνει ότι από το αρχικό αντικείμενο κρατάμε οτιδήποτε ανήκει στην κλάση //BaseException// και απορρίπτουμε το υπόλοιπο. Η απάντηση στο παραπάνω ερώτημα είναι ότι αν και παράγεται ένα αντικείμενο τύπου //DerivedException// αυτό γίνεται //catch// από το πρώτο //catch block//. Μέσα στο //catch block// το αρχικό αντικείμενο αντιγράφεται σε ένα άλλο αντικείμενο τύπου //BaseException//, διότι έχουμε κλήση με τιμή στο //catch block//. Πρακτικά αυτό σημαίνει ότι από το αρχικό αντικείμενο κρατάμε οτιδήποτε ανήκει στην κλάση //BaseException// και απορρίπτουμε το υπόλοιπο.
  
-Ο τρόπος για να δουλέψει σωστά ο παραπάνω κώδικας είναι μέσα στο //catch block// να μην περάσουμε το αντικείμενο γιατί δημιουργείται αντίγραφο, αλλά να περάσουμε μία αναφορά σε αυτό, όπως παρακάτω:+Ο τρόπος για να δουλέψει σωστά ο παραπάνω κώδικας είναι μέσα στο //catch block// να μην περάσουμε το αντικείμενο γιατί δημιουργείται αντίγραφο του, αλλά να περάσουμε μία αναφορά σε αυτό, όπως παρακάτω:
  
 <code cpp ExceptionUse.cpp> <code cpp ExceptionUse.cpp>
 #include <iostream> #include <iostream>
-#include "DerivedException.h"+#include "DerivedException.hpp"
 using namespace std; using namespace std;
  
Line 112: Line 112:
     }     }
   } catch(BaseException &ex) {   } catch(BaseException &ex) {
-    cout << ex.what();+    cout << ex.message();
   } catch(DerivedException &ex) {   } catch(DerivedException &ex) {
-    cout << ex.what();+    cout << ex.message();
   }   }
   return 0;   return 0;
Line 131: Line 131:
  
 <WRAP tip 80% center round> <WRAP tip 80% center round>
-Το πιάσιμο μιας εξαίρεσης με χρήση αναφοράς για αντικείμενα σύνθετου τύπου (όχι char, int, long, double κλπ), διότι //α)// αποφεύγουμε την αντιγραφή του αντικειμένου μέσα στο //catch block// (πιο γρήγορος κώδικας) και //β)// αποφεύγουμε την "αποκοπή" μέρους του αντικειμένου της εξαίρεσης λόγω του χειρισμού της από ένα //catch block// βασικότερου τύπου από τον τύπο του αντικειμένου της εξαίρεσης.+Συνιστάται, η διαχείριση μιας εξαίρεσης με χρήση αναφοράς για αντικείμενα σύνθετου τύπου (δηλαδή όχι τύπου char, int, long, double κλπ), διότι //α)// αποφεύγουμε την αντιγραφή του αντικειμένου μέσα στο //catch block// (πιο γρήγορη κλήση) και //β)// αποφεύγουμε την "αποκοπή" μέρους του αντικειμένου της εξαίρεσης λόγω του χειρισμού της από ένα //catch block// βασικότερου τύπου.
 </WRAP> </WRAP>
  
cpp/exception_inheritance.1557129834.txt.gz · Last modified: 2019/05/06 07:03 (external edit)