cpp:exception
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
cpp:exception [2019/05/06 07:19] – [Stack Unwinding] gthanos | cpp:exception [2019/05/06 07:23] – [Δήλωση των εξαιρέσεων που παράγουν οι συναρτήσεις (exception specifiers)] gthanos | ||
---|---|---|---|
Line 119: | Line 119: | ||
Στο παραπάνω απλό παράδειγμα είναι προφανές ότι είναι πιο απλό να ελέγξει κανείς το μέγεθος της παραμέτρου //size// πριν καλέσει τον κατασκευαστή. Σε αυτή την περίπτωση, | Στο παραπάνω απλό παράδειγμα είναι προφανές ότι είναι πιο απλό να ελέγξει κανείς το μέγεθος της παραμέτρου //size// πριν καλέσει τον κατασκευαστή. Σε αυτή την περίπτωση, | ||
</ | </ | ||
+ | |||
===== Τύποι παραγόμενων εξαιρέσεων ===== | ===== Τύποι παραγόμενων εξαιρέσεων ===== | ||
Line 203: | Line 204: | ||
Στον παραπάνω κώδικα μπορείτε να παρατηρήσετε τα διαφορετικά μηνύματα που παράγονται ανάλογα με τον τύπο της εξαίρεσης. Παρατηρήστε επίσης ότι αν και παράγεται ένα αντικείμενο τύπου //short int//, το οποίο χωράει σε ένα //int// δεν γίνεται κάποια αυτόματη μετατροπή τύπου, ώστε το //catch block// που πιάνει τύπους //int// να πιάσει και αντικείμενα τύπου short int. | Στον παραπάνω κώδικα μπορείτε να παρατηρήσετε τα διαφορετικά μηνύματα που παράγονται ανάλογα με τον τύπο της εξαίρεσης. Παρατηρήστε επίσης ότι αν και παράγεται ένα αντικείμενο τύπου //short int//, το οποίο χωράει σε ένα //int// δεν γίνεται κάποια αυτόματη μετατροπή τύπου, ώστε το //catch block// που πιάνει τύπους //int// να πιάσει και αντικείμενα τύπου short int. | ||
</ | </ | ||
- | |||
- | |||
- | |||
- | ===== Διαχείριση μίας εξαίρεσης και παραγωγή νέας εξαίρεσης κατά την διαχείριση της ===== | ||
- | |||
- | Κάποιες φορές είναι επιθυμητό να διαχειριστούμε μία εξαίρεση προκειμένου να κλείσουμε κάποιο // | ||
- | |||
- | <code cpp PPMImageSample.cpp> | ||
- | #include < | ||
- | #include < | ||
- | #include <ios> | ||
- | #include < | ||
- | |||
- | using namespace std; | ||
- | |||
- | class PPMImage { | ||
- | int width, height, colordepth; | ||
- | int **raster; | ||
- | public: | ||
- | PPMImage(char *filename) { | ||
- | string str; | ||
- | unsigned char red, green, blue; | ||
- | ifstream in(filename); | ||
- | if(!in.is_open()) { | ||
- | std:: | ||
- | throw fex; | ||
- | } | ||
- | try { | ||
- | in >> str; | ||
- | in >> str; | ||
- | width = atoi(str.c_str()); | ||
- | in >> str; | ||
- | height = atoi(str.c_str()); | ||
- | in >> str; | ||
- | colordepth = atoi(str.c_str()); | ||
- | raster = new int*[height]; | ||
- | for(int row=0; row< | ||
- | raster[row] = new int[width]; | ||
- | for(int row=0; row< | ||
- | for(int col=0; col< | ||
- | cin >> str; | ||
- | red = (unsigned char) atoi(str.c_str()); | ||
- | cin >> str; | ||
- | green = (unsigned char) atoi(str.c_str()); | ||
- | cin >> str; | ||
- | blue = (unsigned char) atoi(str.c_str()); | ||
- | raster[row][col] = 0; | ||
- | raster[row][col] = (red << 16) | (green << 8) | blue; | ||
- | } | ||
- | } | ||
- | } | ||
- | catch(std:: | ||
- | cerr << " | ||
- | in.close(); | ||
- | throw ex; | ||
- | } | ||
- | } | ||
- | | ||
- | ~PPMImage() { | ||
- | for(int row=0; row< | ||
- | delete raster[row]; | ||
- | delete raster; | ||
- | } | ||
- | | ||
- | int **getRaster() { return raster; } | ||
- | | ||
- | }; | ||
- | |||
- | int main(int argc, char *argv[]) { | ||
- | PPMImage *imgptr=nullptr; | ||
- | try{ | ||
- | imgptr = new PPMImage(argv[1]); | ||
- | } | ||
- | catch(ios_base:: | ||
- | cerr << "File '" | ||
- | } | ||
- | catch(bad_alloc &ex) { | ||
- | cerr << " | ||
- | if (imgptr!=nullptr) { | ||
- | cerr << " | ||
- | if(imgptr-> | ||
- | cerr << " | ||
- | delete imgptr-> | ||
- | } | ||
- | else { | ||
- | cerr << " | ||
- | } | ||
- | delete imgptr; | ||
- | } | ||
- | else { | ||
- | cerr << " | ||
- | } | ||
- | } | ||
- | delete imgptr; | ||
- | return 0; | ||
- | } | ||
- | </ | ||
- | |||
- | Το ενδεικτικό αρχείο εισόδου είναι το παρακάτω: | ||
- | |||
- | <code cpp 3x2.ppm> | ||
- | P3 | ||
- | 3 -2 255 | ||
- | 255 0 0 255 255 0 0 255 255 | ||
- | 255 0 255 0 255 0 128 128 128 | ||
- | </ | ||
- | |||
- | Από τον παραπάνω κώδικα μπορούμε να συμπεράνουμε τα εξής: | ||
- | - Εφόσον παράγεται ένα // | ||
- | - Εάν εφαρμόσω τον τελεστή **delete** σε ένα δείκτη που έχει την τιμή **nullptr**, | ||
- | |||
- | ==== Ένα 2ο παράδειγμα ==== | ||
- | |||
- | Στο προηγούμενο παράδειγμα κάντε την εξής αλλαγή. Αντικαταστήστε το //catch block// στον κατασκευαστή με το παρακάτω: | ||
- | |||
- | <code cpp> | ||
- | catch(std:: | ||
- | cerr << " | ||
- | in.close(); | ||
- | throw ex; | ||
- | } | ||
- | </ | ||
- | |||
- | Το //exception std:: | ||
- | < | ||
- | $> ./ | ||
- | std:: | ||
- | terminate called after throwing an instance of ' | ||
- | what(): | ||
- | Aborted (core dumped) | ||
- | </ | ||
- | |||
- | Ο λόγος που συμβαίνει το παραπάνω είναι ότι το όταν το //catch block// παράγει και πάλι το // | ||
- | |||
- | <code cpp> | ||
- | catch(std:: | ||
- | cerr << " | ||
- | in.close(); | ||
- | throw; | ||
- | } | ||
- | </ | ||
- | ===== Δήλωση των εξαιρέσεων που παράγουν οι συναρτήσεις (exception specifiers) ===== | ||
- | |||
- | Κατά τη δήλωση μίας συνάρτησης είναι δυνατόν να ορίσετε εάν αυτή μπορεί να παράγει κάποιου είδους // | ||
- | - '' | ||
- | - '' | ||
- | - '' | ||
- | |||
- | Τους παραπάνω ορισμούς είναι δυνατόν να τους συναντήσετε στις // | ||
- | |||
- | /* | ||
- | ===== Function try blocks ===== | ||
- | */ | ||
- | |||
- | |||
- | |||
- | |||
- | |||
cpp/exception.txt · Last modified: 2023/05/15 14:01 by gthanos