This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
cpp:constructors [2020/04/14 07:44] gthanos [Χρήση member initialization list για την αρχικοποίηση των μελών της κλάσης] |
cpp:constructors [2021/05/07 06:11] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Κατασκευαστές της κλάσης ====== | ||
| - | |||
| - | Στο προηγούμενο παράδειγμα της κλάσης // | ||
| - | |||
| - | <code cpp Rectangle.hpp> | ||
| - | #include < | ||
| - | using namespace std; | ||
| - | |||
| - | class Rectangle { | ||
| - | private: | ||
| - | int width, height; | ||
| - | public: | ||
| - | Rectangle(int w, int h); | ||
| - | void setWidth(int w); | ||
| - | void setHeight(int h); | ||
| - | int getWidth() const; | ||
| - | int getHeight() const; | ||
| - | }; | ||
| - | </ | ||
| - | |||
| - | <code cpp Rectangle.cpp> | ||
| - | #include " | ||
| - | |||
| - | Rectangle:: | ||
| - | width = w; height = h; | ||
| - | } | ||
| - | void Rectangle:: | ||
| - | void Rectangle:: | ||
| - | int Rectangle:: | ||
| - | int Rectangle:: | ||
| - | </ | ||
| - | |||
| - | <code cpp RectangleUsage.cpp> | ||
| - | #include " | ||
| - | |||
| - | int main () { | ||
| - | Rectangle rect(5,6); | ||
| - | cout << "area: " << rect.getWidth() * rect.getHeight() << endl; | ||
| - | return 0; | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Για την μεταγλώττιση αρκεί να μεταγλωττισετε κάθε επιμέρους κλάση ξεχωριστά και στη συνέχεια να δημιουργήσετε το τελικό εκτελέσιμο. Στο συγκεκριμένο παράδειγμα, | ||
| - | < | ||
| - | g++ -Wall -g Rectangle.cpp -c | ||
| - | g++ -Wall -g Rectangle.o RectangleUsage.cpp | ||
| - | </ | ||
| - | |||
| - | <WRAP center round info 80%> | ||
| - | Σε αναλογία με τις μεθόδους ο κατασκευαστής μπορεί να οριστεί εντός της κλάσης, | ||
| - | <code cpp Rectangle.cpp> | ||
| - | class Rectangle { | ||
| - | private: | ||
| - | int width, height; | ||
| - | public: | ||
| - | Rectangle(int w, int h){ | ||
| - | width = w; height = h; | ||
| - | } | ||
| - | }; | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | ===== Default κατασκευαστής ===== | ||
| - | |||
| - | Εάν δεν οριστεί κανένας κατασκευαστής σε μία κλάση τότε για την κλάση ορίζεται από τον μεταγλωττιστή ο //default// κατασκευαστής. Ο κατασκευαστής αυτός δεν έχει ορίσματα. Τα πεδία της κλάσης αρχικοποιούνται ως εξής: | ||
| - | - για πεδία που έχουν βασικού τύπους (int, double, char κλπ) οι τιμές είναι τυχαίες. | ||
| - | - για πεδία που περιγράφονται από κλάσεις καλείται ο //default// κατασκευαστής της εκάστοτε κλάσης. | ||
| - | |||
| - | Εάν έχετε δηλώσει τουλάχιστον ένα κατασκευαστή που δεν είναι ο //default// κατασκευαστής χωρίς παραμέτρους τότε ο // | ||
| - | |||
| - | ===== Υπερφόρτωση κατασκευαστών ===== | ||
| - | |||
| - | Σε αναλογία με την [[cpp: | ||
| - | |||
| - | <code cpp Rectangle.hpp> | ||
| - | #include < | ||
| - | #include < | ||
| - | #include < | ||
| - | using namespace std; | ||
| - | |||
| - | class Rectangle { | ||
| - | private: | ||
| - | int width, height; | ||
| - | public: | ||
| - | Rectangle(int w, int h); | ||
| - | Rectangle(int s); | ||
| - | Rectangle(); | ||
| - | void setWidth(int w); | ||
| - | void setHeight(int h); | ||
| - | int getWidth() const; | ||
| - | int getHeight() const; | ||
| - | }; | ||
| - | </ | ||
| - | |||
| - | <code cpp Rectangle.cpp> | ||
| - | #include " | ||
| - | |||
| - | Rectangle:: | ||
| - | width = w; height = h; | ||
| - | } | ||
| - | |||
| - | Rectangle:: | ||
| - | width = s; height = s; | ||
| - | } | ||
| - | |||
| - | Rectangle:: | ||
| - | srand(time(NULL)); | ||
| - | width = rand() % 10 + 1; height = rand() % 10 + 1; | ||
| - | } | ||
| - | |||
| - | void Rectangle:: | ||
| - | void Rectangle:: | ||
| - | int Rectangle:: | ||
| - | int Rectangle:: | ||
| - | |||
| - | </ | ||
| - | |||
| - | <code cpp RectangleUsage.cpp> | ||
| - | #include " | ||
| - | |||
| - | int main () { | ||
| - | Rectangle rect(5,6); | ||
| - | cout << "area: " << rect.getWidth() * rect.getHeight() << endl; | ||
| - | return 0; | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== Χρήση member initialization list για την αρχικοποίηση των μελών της κλάσης ===== | ||
| - | |||
| - | Παραπάνω συναντήσαμε τον κατασκευαστή με δύο ορίσματα | ||
| - | <code cpp> | ||
| - | Rectangle:: | ||
| - | width = w; height = h; | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Αντί για την παραπάνω δήλωση θα μπορούσατε να γράψετε __ισοδύναμα__: | ||
| - | <code cpp> | ||
| - | Rectangle:: | ||
| - | height = h; | ||
| - | } | ||
| - | </ | ||
| - | ή __ισοδύναμα__ | ||
| - | <code cpp> | ||
| - | Rectangle:: | ||
| - | </ | ||
| - | |||
| - | Ο παραπάνω τρόπος γραφής ονομάζεται στη βιβλιογραφία __member initilization list__. Τελικά η κλάση Rectangle μπορεί να γραφεί με χρήση //member initilization list// όπως παρακάτω: | ||
| - | |||
| - | <code cpp Rectangle.hpp> | ||
| - | #include < | ||
| - | #include < | ||
| - | #include < | ||
| - | using namespace std; | ||
| - | |||
| - | class Rectangle { | ||
| - | private: | ||
| - | int width, height; | ||
| - | public: | ||
| - | Rectangle(int w, int h); | ||
| - | Rectangle(int s); | ||
| - | Rectangle(); | ||
| - | void setWidth(int w); | ||
| - | void setHeight(int h); | ||
| - | int getWidth() const; | ||
| - | int getHeight() const; | ||
| - | }; | ||
| - | |||
| - | Rectangle:: | ||
| - | } | ||
| - | |||
| - | Rectangle:: | ||
| - | } | ||
| - | |||
| - | Rectangle:: | ||
| - | srand(time(NULL)); | ||
| - | width = rand() % 10 + 1; height = rand() % 10 + 1; | ||
| - | } | ||
| - | |||
| - | void Rectangle:: | ||
| - | void Rectangle:: | ||
| - | int Rectangle:: | ||
| - | int Rectangle:: | ||
| - | </ | ||
| - | |||
| - | ===== Κλήση ενός κατασκευαστή μέσα από άλλο κατασκευαστή ===== | ||
| - | |||
| - | Συχνά μπορεί να θέλουμε να καλέσουμε μέσα από ένα κατασκευαστή έναν άλλο κατασκευαστή. Μπορείτε να το κάνετε αυτό χρησιμοποιώντας ως οποιαδήποτε άλλη μέθοδο. Στο προηγούμενο παράδειγμα, | ||
| - | |||
| - | <code cpp> | ||
| - | Rectangle:: | ||
| - | Rectangle(s, | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | O ίδιος κώδικας με χρήση // | ||
| - | |||
| - | <code cpp> | ||
| - | Rectangle:: | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== Αρχικοποίηση αντικειμένων που περιέχουν πεδία που περιγράφονται από κλάσεις ===== | ||
| - | |||
| - | Στην προηγούμενη ενότητα είδαμε την κλάση Cuboid που περιγράφει την κλάση του κυβοειδούς και περιέχει ένα πεδίο τύπου Rectangle. Εδώ θα δούμε πως μπορούμε να ορίσουμε ένα ή περισσότερους κατασκευαστές για τη συγκεκριμένη κλάση. | ||
| - | |||
| - | <code cpp Cuboid.hpp> | ||
| - | #include < | ||
| - | using namespace std; | ||
| - | |||
| - | #include " | ||
| - | |||
| - | class Cuboid { | ||
| - | private: | ||
| - | int length; | ||
| - | Rectangle rect; | ||
| - | public: | ||
| - | Cuboid(int w, int h, int l); | ||
| - | Cuboid(Rectangle r, int l); | ||
| - | | ||
| - | void setRectangle(Rectangle r); | ||
| - | Rectangle getRectangle() const; | ||
| - | void setLength(int l); | ||
| - | int getLength() const; | ||
| - | int volume(); | ||
| - | }; | ||
| - | </ | ||
| - | |||
| - | <code cpp Cuboid.cpp> | ||
| - | #include " | ||
| - | |||
| - | Cuboid:: | ||
| - | rect.setWidth(w); | ||
| - | rect.setHeight(h); | ||
| - | length = l; | ||
| - | } | ||
| - | |||
| - | Cuboid:: | ||
| - | rect = r; | ||
| - | | ||
| - | } | ||
| - | |||
| - | void Cuboid:: | ||
| - | Rectangle Cuboid:: | ||
| - | void Cuboid:: | ||
| - | int Cuboid:: | ||
| - | |||
| - | int Cuboid:: | ||
| - | return length * rect.getWidth() * rect.getHeight(); | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Οι παραπάνω δύο κατασκευαστές με χρήση member initialιzation list μπορούν να γραφούν ως εξής: | ||
| - | |||
| - | < | ||
| - | Cuboid:: | ||
| - | Cuboid:: | ||
| - | </ | ||
| - | |||
| - | Στον πρώτο κατασκευαστή με τα δύο ορίσματα γίνεται ανάθεση του αντικειμένου //r// στο πεδίο //rect//, αντιγράφοντας την τιμή κάθε πεδίου της παραμέτρου //r// στο πεδίιο //rect//. Στον 2ο κατασκευαστή με τα τρία ορίσματα καλείται ο κατασκευαστής της κλάσης // | ||
| - | |||