User Tools

Site Tools


cpp:copy_constructors

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revisionBoth sides next revision
cpp:copy_constructors [2020/04/14 14:32] – [Κατασκευαστές Αντιγραφείς] gthanoscpp:copy_constructors [2020/04/14 15:24] gthanos
Line 1: Line 1:
 ====== Κατασκευαστές Αντιγραφείς ====== ====== Κατασκευαστές Αντιγραφείς ======
  
-Στην ενότητα των συναρτήσεων είδαμε [[cpp:functions#κλήση_με_τιμή_και_κλήση_με_αναφορά|την κλήση με τιμή και κλήση με αναφορά]] προκειμένου να περάσουμε παραμέτρους σε μία συνάρτηση. Κατά **την κλήση με τιμή** όταν η παράμετρος είναι ένα αντικείμενο, ένα αντίγραφο του αντικειμένου θα πρέπει να δημιουργηθεί στο //stack// της συνάρτησης που καλείται. Προκειμένου να γίνει αυτό η C++ ορίζει την έννοια του κατασκευαστή αντιγραφέα (//copy constructor//), ο οποίος δημιουργεί ένα αντικείμενο που είναι ακριβές αντίγραφο ενός άλλου αντικειμένου. Δείτε το παρακάτω παράδειγμα της μεθόδου //printArea// η οποία λαμβάνει ως παράμετρο ένα αντικείμενο της κλάσης //Rectangle//.+Στην ενότητα των συναρτήσεων είδαμε [[cpp:functions#κλήση_με_τιμή_και_κλήση_με_αναφορά|την κλήση με τιμή και κλήση με αναφορά]] προκειμένου να περάσουμε παραμέτρους σε μία συνάρτηση. Κατά **την κλήση με τιμή** όταν η παράμετρος είναι ένα αντικείμενο, ένα αντίγραφο του αντικειμένου θα πρέπει να δημιουργηθεί στο //stack// της συνάρτησης που καλείται. Προκειμένου να γίνει αυτό η C++ ορίζει την έννοια του κατασκευαστή αντιγραφέα (//copy constructor//), ο οποίος δημιουργεί ένα αντικείμενο που είναι ακριβές αντίγραφο ενός άλλου αντικειμένου του ίδου τύπου.  
 + 
 +Δείτε το παρακάτω παράδειγμα της μεθόδου //printArea// η οποία λαμβάνει ως παράμετρο ένα αντικείμενο της κλάσης //Rectangle//. 
 + 
 +<code cpp Rectangle.cpp> 
 +#include <iostream> 
 +#include <cstdlib> 
 +#include <ctime> 
 +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(); 
 +    int getHeight(); 
 +}; 
 + 
 +Rectangle::Rectangle(int w, int h) { 
 +  cout << "Calling 2 args constructor" << endl; 
 +  width = w; height = h; 
 +
 + 
 +Rectangle::Rectangle(int s) : { 
 +  cout << "Calling 1 args constructor" << endl; 
 +  width = s; height = s; 
 +
 + 
 +Rectangle::Rectangle() { 
 +  cout << "Calling default constructor" << endl; 
 +  width = height = 0; 
 +
 + 
 +void Rectangle::setWidth(int w) { width = w; } 
 +void Rectangle::setHeight(int h) { height = h; } 
 +int Rectangle::getWidth() { return width; } 
 +int Rectangle::getHeight() { return height; } 
 +</code>
  
 <code cpp foo.cpp> <code cpp foo.cpp>
Line 21: Line 63:
  
 {{ :cpp:cppstackcopyconstructor.png |}} {{ :cpp:cppstackcopyconstructor.png |}}
 +
 +Το ερώτημα είναι με ποιό τρόπο γίνεται η δημιουργία του αντιγράφου του αρχικού αντικειμένου στο //stack//. Μπορείτε να δηλώσετε τον δικό σας κατασκευαστή αντιγραφέα (λεπτομέρειες πιο κάτω..) ή να αφήσετε τον //compiler// να δηλώσει τον //default//. Ο //default// κατασκευαστής αντιγραφέας δημιουργεί το νέο αντικείμενο από το παλιό αντιγράφοντας τα πεδία πεδίο προς πεδιο. Εάν αυτός ο τρόπος σας ικανοποιεί, τότε δεν χρειάζεται να κάνετε κάτι περισσότερο. Εάν όμως η παραπάνω μεθοδολογία δεν είναι ικανοποιητική, είστε αναγκασμένοι να ορίσετε τον δικό σας κατασκευαστή αντιγραφέα.
  
 ===== Ορισμός ενός κατασκευαστή αντιγραφέα ===== ===== Ορισμός ενός κατασκευαστή αντιγραφέα =====
  
-Ένας κατασκευαστής αντιγραφέας για την κλάση Rectangle θα μπορούσε να είναι ο εξής:+Ένας κατασκευαστής αντιγραφέας για την παραπάνω κλάση //Rectangle// θα μπορούσε να είναι ο εξής:
  
 <code cpp> <code cpp>
 Rectangle::Rectangle(Rectangle &r) { Rectangle::Rectangle(Rectangle &r) {
-  width = r.width; height = r.height;+  width = r.width;  
 +  height = r.height;
 } }
 </code> </code>
Line 34: Line 79:
 <code cpp> <code cpp>
 Rectangle::Rectangle(const Rectangle &r) { Rectangle::Rectangle(const Rectangle &r) {
-  width = r.width; height = r.height;+  width = r.width;  
 +  height = r.height;
 } }
 </code> </code>
  
-Στη 2η περίπτωση, η μεταβλητή //r// δηλώνεται ως //const// διότι κατά την εκτέλεση του κατασκευαστή αντιγραφέα το αντικείμενο //r// δεν μεταβάλλεται. Συνολικά η κλάση //Rectangle// διαμορφώνεται ως εξής:+Και οι δύο παραπάνω κατασκευαστές δηλώνουν ένα κατασκευαστή αντιγραφέα. Στη δεύτερη περίπτωση, η μεταβλητή //r// δηλώνεται ως //const// διότι κατά την εκτέλεση του κατασκευαστή αντιγραφέα το αντικείμενο //r// δεν μεταβάλλεται. Συνολικά η κλάση //Rectangle// διαμορφώνεται ως εξής:
  
 <code cpp Rectangle.hpp> <code cpp Rectangle.hpp>
Line 53: Line 99:
     Rectangle(int s);     Rectangle(int s);
     Rectangle();     Rectangle();
-    Rectangle(Rectangle &r);+    Rectangle(Rectangle& r);
     void setWidth(int w);     void setWidth(int w);
     void setHeight(int h);     void setHeight(int h);
Line 65: Line 111:
 } }
  
-Rectangle::Rectangle(int s) : Rectangle(s,s) {+Rectangle::Rectangle(int s) : {
   cout << "Calling 1 args constructor" << endl;   cout << "Calling 1 args constructor" << endl;
 +  width = s; height = s;
 } }
  
-Rectangle::Rectangle() : Rectangle(0,0) {+Rectangle::Rectangle() {
   cout << "Calling default constructor" << endl;   cout << "Calling default constructor" << endl;
 +  width = height = 0;
 } }
  
-Rectangle::Rectangle(Rectangle &r) { +Rectangle::Rectangle(Rectangle& r) { 
-  cout << "Calling copy constructor" << endl; +  cout << Calling copy constructor" << endl; 
-  width = r.width; height = r.height;+  width = r.width; 
 +  height = r.height;
 } }
  
Line 82: Line 131:
 int Rectangle::getWidth() { return width; } int Rectangle::getWidth() { return width; }
 int Rectangle::getHeight() { return height; } int Rectangle::getHeight() { return height; }
- 
-void printArea(Rectangle r) { 
-  cout << " area: " << r.getWidth() * r.getHeight() << endl; 
-} 
 </code> </code>
  
cpp/copy_constructors.txt · Last modified: 2022/05/12 19:41 by gthanos