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 [2018/05/20 14:26] – [Δήλωση των εξαιρέσεων που παράγουν οι συναρτήσεις (exception specifiers)] gthanos | cpp:exception [2019/03/07 15:22] – [Κληρονομικότητα εξαιρέσεων] gthanos | ||
---|---|---|---|
Line 78: | Line 78: | ||
Vector:: | 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 204: | Line 204: | ||
</ | </ | ||
- | ===== Κληρονομικότητα ===== | + | ===== Κληρονομικότητα |
Ας υποθέσουμε ότι έχουμε τη σχέση κληρονομικότητας μεταξύ των κλάσεων **BaseException** και **DerivedException**, | Ας υποθέσουμε ότι έχουμε τη σχέση κληρονομικότητας μεταξύ των κλάσεων **BaseException** και **DerivedException**, | ||
Line 338: | Line 338: | ||
<WRAP tip 80% center round> | <WRAP tip 80% center round> | ||
- | Το πιάσιμο μιας εξαίρεσης με χρήση αναφοράς για αντικείμενα σύνθετους τύπου (όχ char, int, long, double κλπ), διότι //α)// αποφεύγουμε την αντιγραφή του αντικειμένου μέσα στο //catch block// (πιο γρήγορος κώδικας) και //β)// αποφεύγουμε την " | + | Το πιάσιμο μιας εξαίρεσης με χρήση αναφοράς για αντικείμενα σύνθετου τύπου (όχι char, int, long, double κλπ), διότι //α)// αποφεύγουμε την αντιγραφή του αντικειμένου μέσα στο //catch block// (πιο γρήγορος κώδικας) και //β)// αποφεύγουμε την " |
</ | </ | ||
Line 344: | Line 344: | ||
Είναι προφανές ότι η σειρά των //catch blocks// θα έπρεπε να είναι η αντίστροφη (πρώτα το //catch block// για την αναφορά τύπου // | Είναι προφανές ότι η σειρά των //catch blocks// θα έπρεπε να είναι η αντίστροφη (πρώτα το //catch block// για την αναφορά τύπου // | ||
</ | </ | ||
+ | |||
===== Stack Unwinding ===== | ===== Stack Unwinding ===== | ||
Line 416: | Line 417: | ||
{{ : | {{ : | ||
- | ===== Κλείσιμο ανοιχτών resources όταν συμβεί ένα exception | + | ===== Διαχείριση μίας εξαίρεσης και παραγωγή |
- | 1. Διάβασμα από αρχείο και | + | Κάποιες φορές είναι επιθυμητό να διαχειριστούμε μία εξαίρεση προκειμένου να κλείσουμε κάποιο // |
+ | <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) ===== | ===== Δήλωση των εξαιρέσεων που παράγουν οι συναρτήσεις (exception specifiers) ===== | ||
Line 429: | Line 564: | ||
Τους παραπάνω ορισμούς είναι δυνατόν να τους συναντήσετε στις // | Τους παραπάνω ορισμούς είναι δυνατόν να τους συναντήσετε στις // | ||
+ | /* | ||
===== Function try blocks ===== | ===== Function try blocks ===== | ||
- | + | */ | |
- | ===== Η κλάση std:: | + | |
cpp/exception.txt · Last modified: 2023/05/15 14:01 by gthanos