cpp:exception
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
cpp:exception [2018/05/18 13:44] – [Κληρονομικότητα] gthanos | cpp:exception [2023/05/15 14:01] (current) – gthanos | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Διαχείριση Εξαιρέσεων ====== | + | ====== |
- | Ας εξετάσουμε την κλάση **Vector** που είδαμε στην υπερφόρτωση | + | Ας εξετάσουμε την κλάση **Vector** που είδαμε στην |
- | <code cpp Vector.cpp> | + | <code cpp Vector.hpp> |
#include < | #include < | ||
#include < | #include < | ||
Line 11: | Line 11: | ||
class Vector { | class Vector { | ||
int *array; | int *array; | ||
- | | + | |
| | ||
public: | public: | ||
- | Vector(int length=0); | + | Vector(long length=0); |
~Vector(); | ~Vector(); | ||
int & | int & | ||
}; | }; | ||
+ | </ | ||
- | Vector:: | + | <code cpp Vector.cpp> |
+ | #include " | ||
+ | Vector:: | ||
size = length; | size = length; | ||
array = new (nothrow) int[size]; | array = new (nothrow) int[size]; | ||
Line 35: | Line 38: | ||
int & | int & | ||
- | if(pos>=length()) { | + | if(pos>=size) { |
cerr << " | cerr << " | ||
| | ||
Line 43: | Line 46: | ||
</ | </ | ||
- | Αν και η παραπάνω διαδικασία δεν είναι λανθασμένη, | + | Αν και η παραπάνω διαδικασία δεν είναι λανθασμένη, |
<code cpp VectorUse.cpp> | <code cpp VectorUse.cpp> | ||
- | #include " | + | #include " |
int main() { | int main() { | ||
- | | + | |
cout << "Enter verctor size: "; | cout << "Enter verctor size: "; | ||
cin >> size; | cin >> size; | ||
Line 58: | Line 61: | ||
</ | </ | ||
- | Η παραγωγή ενός exception μπορεί να επιλύσει πιο αποτελεσματικά το παραπάνω πρόβλημα διότι | + | Η παραγωγή ενός |
- | <code cpp Vector.cpp> | + | <code cpp Vector.hpp> |
#include < | #include < | ||
#include < | #include < | ||
Line 68: | Line 71: | ||
class Vector { | class Vector { | ||
int *array; | int *array; | ||
- | | + | |
| | ||
public: | public: | ||
- | Vector(int length=0); | + | Vector(long length=0); |
~Vector(); | ~Vector(); | ||
int & | int & | ||
}; | }; | ||
- | Vector:: | + | </ |
+ | |||
+ | <code cpp Vector.cpp> | ||
+ | #include " | ||
+ | |||
+ | Vector:: | ||
size = length; | size = length; | ||
- | array = new (nothrow) | + | array = new int[size]; |
for(int i=0; i<size; i++) | for(int i=0; i<size; i++) | ||
array[i] = 0; | array[i] = 0; | ||
Line 97: | Line 105: | ||
<code cpp VectorUse.cpp> | <code cpp VectorUse.cpp> | ||
- | #include " | + | #include " |
int main() { | int main() { | ||
- | | + | |
- | | + | |
- | cout << "Enter verctor size: "; | + | cout << "Enter verctor size: "; |
- | cin >> size; | + | cin >> size; |
- | try { | + | try { |
- | Vector v(size); | + | Vector v(size); |
- | } catch(std:: | + | } catch(std:: |
- | cout << "Vector size should be a positive integer! Retry...\n"; | + | std::cout << "Allocation failure!\n"; |
- | continue; | + | |
- | } | + | } |
- | | + | |
- | v.valueAt(i) = 100-1; | + | |
- | } while(size< | + | |
} | } | ||
</ | </ | ||
<WRAP tip 80% center round> | <WRAP tip 80% center round> | ||
- | Αν και στο παραπάνω απλό παράδειγμα είναι προφανές ότι είναι πιο απλό να ελέγξει κανείς το μέγεθος της παραμέτρου size πριν καλέσει τον κατασκευαστή, κάτι τέτοιο | + | Στο παραπάνω απλό παράδειγμα είναι προφανές ότι είναι πιο απλό να ελέγξει κανείς το μέγεθος της παραμέτρου |
</ | </ | ||
+ | |||
===== Τύποι παραγόμενων εξαιρέσεων ===== | ===== Τύποι παραγόμενων εξαιρέσεων ===== | ||
Line 133: | Line 140: | ||
===== Δημιουργία και διαχείριση της εξαίρεσης ===== | ===== Δημιουργία και διαχείριση της εξαίρεσης ===== | ||
- | Όπως σε όλες τις γλώσσες αντικειμενοστραφούς προγραμματισμού η παραγωγή μιας εξαίρεσης θα πρέπει να γίνει μέσα σε ένα //try block// και η διαχείριση της μέσα σε ένα //catch block// που ακολουθεί το //try block//. Δείτε το παρακάτω ενδεικτικό παράδειγμα. | + | Όπως σε όλες τις γλώσσες αντικειμενοστραφούς προγραμματισμού η παραγωγή μιας εξαίρεσης θα πρέπει να γίνει μέσα σε ένα //try block// και η διαχείριση της μέσα σε ένα //catch block// που ακολουθεί το //try block//. Δείτε το παρακάτω ενδεικτικό παράδειγμα, όπου ανάλογα με την είσοδο που βάζει ο χρήστης παράγεται διαφορετικού τύπου // |
<code cpp ExceptionHandling.cpp> | <code cpp ExceptionHandling.cpp> | ||
Line 151: | Line 158: | ||
cout << "Enter option (1-5): "; | cout << "Enter option (1-5): "; | ||
cin >> option; | cin >> option; | ||
- | | + | |
MyException ex; | MyException ex; | ||
switch(option) { | switch(option) { | ||
Line 164: | Line 171: | ||
break; | break; | ||
case 4: | case 4: | ||
- | throw string(" | + | throw string(" |
break; | break; | ||
case 5: | case 5: | ||
Line 170: | Line 177: | ||
break; | break; | ||
default: | default: | ||
- | c = -10; throw c; // throw a character | + | c = -10; |
+ | | ||
break; | break; | ||
} | } | ||
Line 183: | Line 191: | ||
} catch(const MyException &ex) { | } catch(const MyException &ex) { | ||
cout << "Got '"<< | cout << "Got '"<< | ||
- | } catch(...) { | + | } catch(...) { // catch any exception not caught above! |
cout << "Got an exception of unknown type!\n"; | cout << "Got an exception of unknown type!\n"; | ||
} | } | ||
Line 190: | Line 198: | ||
</ | </ | ||
- | < | + | < |
- | Στον παραπάνω κώδικα | + | Στον παραπάνω κώδικα το //catch block// |
- | </ | + | <code cpp> |
- | + | } catch(...) { // catch any exception not caught above! | |
- | ===== Κληρονομικότητα ===== | + | |
- | + | ||
- | Ας υποθέσουμε ότι έχουμε τη σχέση κληρονομικότητας μεταξύ των κλάσεων **IDException** και **CountedIDException**, | + | |
- | + | ||
- | <code cpp BaseException.h> | + | |
- | class BaseException: | + | |
- | protected: | + | |
- | | + | |
- | public: | + | |
- | BaseException(int a) { this->a = a; } | + | |
- | const char* what() const throw() { | + | |
- | | + | |
- | sprintf(s, | + | |
- | return s; | + | |
} | } | ||
- | }; | ||
</ | </ | ||
+ | διαχειρίζεται όλους τους τύπους εξαιρέσεων που δεν διαχειρίστηκαν από τα παραπάνω //catch blocks//. Τοποθετώντας ένα //catch block// αυτής της μορφής είναι δυνατόν να εφαρμόσετε ένα τελικό έλεγχο για τύπους εξαιρέσεων που δεν έχετε προβλέψει ότι μπορούν να παραχθούν από τον κώδικα σας. | ||
- | <code cpp CountedIDException.h> | + | Εφόσον, |
- | #include " | + | </WRAP> |
- | class DerivedException: | + | |
- | int b; | + | |
- | public: | + | |
- | DerivedException(int a, int b): Base(a) { this->b = b; } | + | |
- | const char* what() const throw() { | + | |
- | char s[64]; | + | |
- | sprintf(s, " | + | |
- | return s; | + | |
- | } | + | |
- | }; | + | |
- | </code> | + | |
- | <code cpp ExceptionUse.cpp> | + | <WRAP tip 80% center round> |
- | # | + | Στον παραπάνω κώδικα μπορείτε να παρατηρήσετε τα διαφορετικά μηνύματα που παράγονται ανάλογα με τον τύπο της εξαίρεσης. Παρατηρήστε, |
- | using namespace std; | + | </WRAP> |
- | int main() { | + | <WRAP tip 80% center round> |
- | try { | + | Στον παραπάνω κώδικα παρατηρήστε ότι για τα αντικείμενα τύπου // |
- | } catch(BaseException ex) { | + | </WRAP> |
- | cout << ex.what(); | + | |
- | } catch(DerivedException ex) { | + | |
- | cout << ex.what(); | + | |
- | } | + | |
- | return 0; | + | |
- | } | + | |
- | </code> | + | |
cpp/exception.txt · Last modified: 2023/05/15 14:01 by gthanos