====== Δημιουργία αντικειμένων ======
Η δημιουργία αντικειμένων γίνεται με κλήση του αντίστοιχου κατασκευαστή ως εξής:
#include
using namespace std;
class Rectangle {
private:
int width, height;
public:
Rectangle(int w, int h);
Rectangle(int s);
Rectangle();
~Rectangle();
int getWidth() const;
int getHeight() const;
void setWidth(int w);
void setHeight(int h);
};
#include "Rectangle.hpp"
Rectangle::Rectangle(int w, int h): width(w), height(h) {
std::cout << "Constructor with 2 parameters!\n";
}
Rectangle::Rectangle(int s) : width(s), height(s) {
std::cout << "Constructor with 1 parameter!\n";
}
Rectangle::Rectangle(): width(0), height(0) {
std::cout << "Constructor with 0 parameters!\n";
}
Rectangle::~Rectangle() {
std::cout << "Rectangle destructor!\n";
}
int Rectangle::getWidth() const { return width;}
int Rectangle::getHeight() const { return height;}
void Rectangle::setWidth(int w) { width = w; }
void Rectangle::setHeight(int h) { height = h; }
#include "Rectangle.hpp"
int main() {
Rectangle rect1(3,4);
Rectangle rect2(5);
Rectangle rect3;
}
Ο παραπάνω κώδικας δημιουργεί τρία (3) αντικείμενα της κλάσης //Rectangle// το αντικείμενο //rect1// με πλευρές 3 και 4, το //rect2// με πλευρές κοινού μήκους 5 και το αντικείμενο //rect3// που έχει μηδενικές τιμές.
Παρατηρήστε ότι για το τελευταίο αντικείμενο δεν χρησιμοποιούνται παρενθέσεις κατά την κλήση του καστασκευαστή, όπως πιθανόν θα περιμένατε
Rectangle rect3();
Η χρήση παρενθέσεων δεν είναι απαραίτητη, αλλά ούτε και λανθασμένη (έκδοση g++ 7.x.x ή νεότερη)
===== Εναλλακτικοί τρόποι κλήσης του κατασκευαστή της κλάσης =====
Εκτός από την χρήση παρενθέσεων για την κλήση του καστασκευαστή της κλάσης όταν αυτός έχει ορίσματα υπάρχουν οι παρακάτω επιπλέον τρόποι κλήσης κατασκευαστών:
=== 1. Κατασκευαστές με μόνο μία παράμετρο ===
Στην περίπτωση που έχουμε μόνο μία παράμετρο μπορούμε να καλέσουμε τον κατασκευαστή της κλάσης με χρήση του τελεστή ίσον ('=') ως εξής:
class_name object_name = initialization_value;
Για παράδειγμα, για την κλάση //Rectangle// στη συνάρτηση //main// μπορείτε να γράψετε
int main () {
Rectangle rect=5;
cout << "area: " << rect.getWidth() * rect.getHeight() << endl;
return 0;
}
Σε αυτή την περίτπωση καλείται ο κατασκευαστής που έχει ένα μόνο όρισμα το οποίο λαμβάνει την τιμή 5. Το εμβαδό του παραλληλογράμμου που εκτυπώνεται είναι 25 (5x5).
=== 2. Χρήση αγκίστρων αντί για παρενθέσεις ===
Η C++ δίνει την δυνατότητα χρήσης αγκίστρων αντί για παρενθέσεις προκειμένου να καλέσουμε τον κατασκευαστή της κλάσης. Ο τρόπος αυτός έχει τις εξής δύο παραλαγές:
== Σε αναλογία με τη χρήση παρενθέσεων ==
int main () {
Rectangle rect {5,6}; // calls Rectangle(int w, int h)
cout << "area: " << rect.getWidth() * rect.getHeight() << endl;
return 0;
}
Καλείται ο κατασκευαστής της κλάσης με δύο ορίσματα (//width=5, height=6//).
== Με χρήση του τελεστή = πριν τα άγκιστρα ==
int main () {
Rectangle rect = {5,6}; // καλεί Rectangle(int w, int h)
Rectangle rects[2] = {{4,5}, {5,6}}; // καλεί Rectangle(int w, int h) για κάθε θέση του πίνακα
cout << "[rect ] area: " << rect.getWidth() * rect.getHeight() << endl;
cout << "[rects[0]] area: " << rects[0].getWidth() * rects[0].getHeight() << endl;
cout << "[rects[1]] area: " << rects[1].getWidth() * rects[1].getHeight() << endl;
return 0;
}
Οι παραπάνω τρόποι είναι ισοδύναμοι εάν πρόκειται να αρχικοποιήσουμε ένα μεμονομένο αντικείμενο. Στην περίπτωση που θέλουμε να αρχικοποιήσουμε πίνακες από αντικείμενα, μόνο η χρήση του τελεστή ίσον ('=') πριν από τα άγκιστρα επιτρέπει την παραπάνω αρχικοποίηση σε μία εντολή.
===== Δημιουργία αντικειμένων μέσω δυναμικής δέσμευσης της απαιτούμενης μνήμης =====
Τα παραδείγματα που είδαμε μέχρι τώρα δημιουργούν αντικείμενα μέσα στο //stack// της διεργασίας. Εάν θέλουμε να δημιουργήσουμε αντικείμενα τα οποία είναι αποθηκευμένα στο //heap//, δηλαδή δεσμεύεται δυναμικά μνήμη για αυτά, θα πρέπει να το κάνουμε μέσω του τελεστή [[cpp:dynamic_memory|**new** που είδαμε προηγούμενα]] ως εξής:
#include "Rectangle.hpp"
int main () {
Rectangle *rect;
rect = new Rectangle(5,6); // Δέσμευση της μνήμης για ένα αντικείμενο τύπου Rectangle
// και αρχικοποίηση του με τιμές width=5, height=6.
/*
* do fancy things here...
*/
delete rect; // Απελευθέρωση της μνήμης που δεσμεύτηκε προηγούμενα.
// Καλείται ο καταστροφέας της κλάσης εάν υπάρχει.
return 0;
}
Όταν ολοκληρωθεί ο κύκλος ζωής του αντικειμένου θα πρέπει να διαγραφεί το αντικείμενο μέσω του τελεστή //delete//. Η χρήση του τελεστή //delete// καλεί πριν την καταστροφή του αντικειμένου τον καταστροφέα της κλάσης. Κατεβάστε και μεταγλωττίστε τον παραπάνω κώδικα για να δείτε τα μηνύματα που εκτυπώνονται.