This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision | Previous revision | ||
|
cpp:object_creation [2021/05/07 06:22] |
cpp:object_creation [2021/05/07 07:22] gthanos [Δημίουργία αντικείμένων στο Heap] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Δημιουργία αντικειμένων ====== | ||
| + | |||
| + | Η δημιουργία αντικειμένων γίνεται με κλήση του αντίστοιχου κατασκευαστή ως εξής: | ||
| + | <code c++ Rectangle.hpp> | ||
| + | #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); | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | <code cpp Rectangle.cpp> | ||
| + | #include " | ||
| + | |||
| + | Rectangle:: | ||
| + | std::cout << " | ||
| + | } | ||
| + | Rectangle:: | ||
| + | std::cout << " | ||
| + | } | ||
| + | Rectangle:: | ||
| + | std::cout << " | ||
| + | } | ||
| + | |||
| + | Rectangle:: | ||
| + | std::cout << " | ||
| + | } | ||
| + | |||
| + | int Rectangle:: | ||
| + | int Rectangle:: | ||
| + | void Rectangle:: | ||
| + | void Rectangle:: | ||
| + | </ | ||
| + | |||
| + | <code cpp RectangleUsage.cpp> | ||
| + | #include " | ||
| + | |||
| + | int main() { | ||
| + | Rectangle rect1(3,4); | ||
| + | Rectangle rect2(5); | ||
| + | Rectangle rect3; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Ο παραπάνω κώδικας δημιουργεί τρία (3) αντικείμενα της κλάσης // | ||
| + | |||
| + | <WRAP center round tip 80%> | ||
| + | Παρατηρήστε ότι για το τελευταίο αντικείμενο δεν χρησιμοποιούνται παρενθέσεις κατά την κλήση του καστασκευαστή, | ||
| + | <code c++> | ||
| + | Rectangle rect3(); | ||
| + | </ | ||
| + | Η χρήση παρενθέσεων δεν είναι απαραίτητη, | ||
| + | </ | ||
| + | |||
| + | ===== Εναλλακτικοί τρόποι κλήσης του κατασκευαστή της κλάσης ===== | ||
| + | |||
| + | Εκτός από την χρήση παρενθέσεων για την κλήση του καστασκευαστή της κλάσης όταν αυτός έχει ορίσματα υπάρχουν οι παρακάτω επιπλέον τρόποι κλήσης κατασκευαστών: | ||
| + | |||
| + | === 1. Κατασκευαστές με μόνο μία παράμετρο === | ||
| + | |||
| + | Στην περίπτωση που έχουμε μόνο μία παράμετρο μπορούμε να καλέσουμε τον κατασκευαστή της κλάσης με χρήση του τελεστή ίσον (' | ||
| + | < | ||
| + | Για παράδειγμα, | ||
| + | <code c++> | ||
| + | int main () { | ||
| + | Rectangle rect=5; | ||
| + | cout << "area: " << rect.getWidth() * rect.getHeight() << endl; | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Σε αυτή την περίτπωση καλείται ο κατασκευαστής που έχει ένα μόνο όρισμα το οποίο λαμβάνει την τιμή 5. Το εμβαδό του παραλληλογράμμου που εκτυπώνεται είναι 25 (5x5). | ||
| + | |||
| + | === 2. Χρήση αγκίστρων αντί για παρενθέσεις === | ||
| + | |||
| + | Η C++ δίνει την δυνατότητα χρήσης αγκίστρων αντί για παρενθέσεις προκειμένου να καλέσουμε τον κατασκευαστή της κλάσης. Ο τρόπος αυτός έχει τις εξής δύο παραλαγές: | ||
| + | |||
| + | == Σε αναλογία με τη χρήση παρενθέσεων == | ||
| + | |||
| + | <code 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// | ||
| + | |||
| + | == Με χρήση του τελεστή = πριν τα άγκιστρα == | ||
| + | |||
| + | <code c++ RectangleInitialization.cpp> | ||
| + | int main () { | ||
| + | Rectangle rect = {5, | ||
| + | Rectangle rects[2] = {{4,5}, {5,6}}; // καλεί Rectangle(int w, int h) για κάθε θέση του πίνακα | ||
| + | cout << " | ||
| + | cout << " | ||
| + | cout << " | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Οι παραπάνω τρόποι είναι ισοδύναμοι εάν πρόκειται να αρχικοποιήσουμε ένα μεμονομένο αντικείμενο. Στην περίπτωση που θέλουμε να αρχικοποιήσουμε πίνακες από αντικείμενα, | ||
| + | |||
| + | ===== Δημιουργία αντικειμένων μέσω δυναμικής δέσμευσης της απαιτούμενης μνήμης ===== | ||
| + | |||
| + | Τα παραδείγματα που είδαμε μέχρι τώρα δημιουργούν αντικείμενα μέσα στο //stack// της διεργασίας. Εάν θέλουμε να δημιουργήσουμε αντικείμενα τα οποία είναι αποθηκευμένα στο //heap//, δηλαδή δεσμεύεται δυναμικά μνήμη για αυτά, θα πρέπει να το κάνουμε μέσω του τελεστή [[cpp: | ||
| + | |||
| + | <code cpp RectangleInHeap.cpp> | ||
| + | #include " | ||
| + | |||
| + | int main () { | ||
| + | Rectangle *rect; | ||
| + | rect = new Rectangle(5, | ||
| + | // και αρχικοποίηση του με τιμές width=5, height=6. | ||
| + | /* | ||
| + | * do fancy things here... | ||
| + | */ | ||
| + | |||
| + | delete rect; // Απελευθέρωση της μνήμης που δεσμεύτηκε προηγούμενα. | ||
| + | // Καλείται ο καταστροφέας της κλάσης εάν υπάρχει. | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Όταν ολοκληρωθεί ο κύκλος ζωής του αντικειμένου θα πρέπει να διαγραφεί το αντικείμενο μέσω του τελεστή //delete//. Η χρήση του τελεστή //delete// καλεί πριν την καταστροφή του αντικειμένου τον καταστροφέα της κλάσης. Κατεβάστε και μεταγλωττίστε τον παραπάνω κώδικα για να δείτε τα μηνύματα που εκτυπώνονται. | ||