This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision | Previous revision | ||
|
cpp:constructors [2021/05/07 06:11] |
cpp:constructors [2021/05/07 07:11] gthanos [Κατασκευαστές της κλάσης] |
||
|---|---|---|---|
| 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; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <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; | ||
| + | } | ||
| + | }; | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | === Μεταγλώττιση === | ||
| + | |||
| + | Για την μεταγλώττιση αρκεί να μεταγλωττίσετε κάθε επιμέρους αρχείο κλάσης ξεχωριστά και στη συνέχεια να δημιουργήσετε το τελικό εκτελέσιμο. Στο συγκεκριμένο παράδειγμα, | ||
| + | < | ||
| + | g++ -Wall -g Rectangle.cpp -c | ||
| + | g++ -Wall -g Rectangle.o RectangleUsage.cpp | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== 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; | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | <code cpp Rectangle.cpp> | ||
| + | #include " | ||
| + | |||
| + | 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, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Ο ίδιος κώδικας με χρήση //member initialization list// μπορεί να γραφεί ως εξής: | ||
| + | |||
| + | <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//. Στον δεύτερο κατασκευαστή με τα τρία ορίσματα καλείται ο κατασκευαστής της κλάσης // | ||
| + | |||