User Tools

Site Tools


cpp:destructors

Καταστροφείς της κλάσης

Εκτός από τον κατασκευαστή μίας κλάσης, στη C++ έχουμε τη δυνατότητα (και συχνά οφείλουμε) να ορίσουμε και τον καταστροφέα της. Ο καταστροφέας καλείται κατά την καταστροφή του αντικειμένου, ώστε να γίνουν οι απαραίτητες εργασίες “καθαρισμού”. Για παράδειγμα, είναι πιθανόν κατά την δημιουργία του αντικειμένου στον κατασκευαστή να έχει δεσμευθεί μνήμη την οποία κατά την καταστροφή του πρέπει να ελευθερώσουμε. Επιπλέον, μπορεί να έχουν ανοιχθεί στον κατασκευαστή αρχεία ή άλλοι πόροι του συστήματος τα οποία κατά την καταστροφή του αντικειμένου πρέπει να τα κλείσουμε. Στη διεθνή βιβλιογραφία ο καταστροφέας της κλάσης απαντάται ως destructor.

Στο παρακάτω παράδειγμα βλέπετε την κλάση Rectangle όπου τα πεδία width και height είναι δείκτες σε ακέραιο και όχι ακέραιοι. Σε αυτή την περίπτωση θα πρέπει να δεσμεύουμε την απαραίτητη μνήμη με χρήση του τελεστή new στον κατασκευαστή, ενώ στον καταστροφέα την κλάσης απελευθερώνουμε τη μνήμη που δεσμεύσαμε προηγούμενα.

Rectangle.hpp
#include <iostream>
#include <cstdlib>
using namespace std;
 
class Rectangle {
  private:
    int* width;
    int* height;
  public:
    Rectangle(int w, int h);
    ~Rectangle();
    void setWidth(int w);
    void setHeight(int h);
    int getWidth();
    int getHeight();
};
Rectangle.cpp
#include "Rectangle.hpp"
 
Rectangle::Rectangle(int w, int h) {
  width = new (nothrow) int;    
  height = new (nothrow) int;
  if(width == NULL || height == NULL) {
    cerr << "Memory allocation failure!\n";
    exit(-1);
  }
  *width = w; *height = h;
  cout << "Constructing rectangle (w:"<< *width <<", h:"<<*height<<")\n";
}
 
Rectangle::~Rectangle() {
  cout << "Destructing rectangle (w:"<< *width <<", h:"<<*height<<")\n";
  delete width;
  delete height;
}
 
void Rectangle::setWidth(int w) { *width = w; }
void Rectangle::setHeight(int h) { *height = h; }
int Rectangle::getWidth() { return *width; }
int Rectangle::getHeight() { return *height; }
RectangleUsage.cpp
#include "Rectangle.hpp"
 
int main () {
  Rectangle rect(5,6);
  cout << "area: " << rect.getWidth() * rect.getHeight() << endl;
  return 0;
}

Στο παραπάνω παράδειγμα, εάν δεν οριστεί καταστροφέας η μνήμη θα παραμείνει δεσμευμένη μέχρι να τερματιστεί το πρόγραμμα και η μνήμη να ελευθερωθεί από το λειτουργικό μαζί με όλους τους πόρους του προγράμματος. Σε αυτή την περίπτωση το πρόγραμμα κατά την εκτέλεση του δεν απελευθερώνει τη μνήμη που δέσμευσε.

cpp/destructors.txt · Last modified: 2021/05/17 06:36 (external edit)