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 revision
Previous revision
Next revisionBoth sides next revision
cpp:copy_constructors [2017/05/10 06:14] – [Ορισμός ενός κατασκευαστή αντιγραφέα] gthanoscpp:copy_constructors [2019/04/19 09:37] – [Ορισμός ενός κατασκευαστή αντιγραφέα] gthanos
Line 8: Line 8:
 #include "Rectangle.cpp" #include "Rectangle.cpp"
  
-void printArea(Rectangle r) {+void printArea(const Rectangle r) {
   cout << " area: " << r.getArea() << endl;   cout << " area: " << r.getArea() << endl;
 } }
Line 24: Line 24:
 ===== Ορισμός ενός κατασκευαστή αντιγραφέα ===== ===== Ορισμός ενός κατασκευαστή αντιγραφέα =====
  
-Ένας κατασκευαστής αντιγραφέας για την κλάση Rectangle ορίζεται ως εξής:+Ένας κατασκευαστής αντιγραφέας για την κλάση Rectangle θα μπορούσε να είναι ο εξής:
  
 <code cpp> <code cpp>
-Rectangle::Rectangle(Rectangle &r) {+Rectangle::Rectangle(const Rectangle &r) { 
 +  width = r.width; height = r.height; 
 +
 +</code> 
 +ή ο παρακάτω 
 +<code cpp> 
 +Rectangle::Rectangle(const Rectangle &r) {
   width = r.width; height = r.height;   width = r.width; height = r.height;
 } }
 </code> </code>
  
-Συνολικά η κλάση //Rectangle// διαμορφώνεται ως εξής:+Στη 2η περίπτωση, η μεταβλητή //r// δηλώνεται ως //const// διότι κατά την εκτέλεση του κατασκευαστή αντιγραφέα το αντικείμενο //r// δεν μεταβάλλεται. Συνολικά η κλάση //Rectangle// διαμορφώνεται ως εξής:
  
 <code cpp Rectangle.cpp> <code cpp Rectangle.cpp>
Line 78: Line 84:
  
 <WRAP center round tip 80%> <WRAP center round tip 80%>
-Εάν δεν ορίσετε ένα δικό σας κατασκευαστή αντιγραφέα ο //compiler// δημιουργεί έναν από μόνος του αντιγράφοντας τα περιεχόμενα του αρχικού αντικειμένου στο νέο πεδίο προς πεδίο.+Εάν δεν ορίσετε ένα δικό σας κατασκευαστή αντιγραφέα ο //compiler// δημιουργεί τον //default copy constructor//. Ο //default// αντιγράφει τα περιεχόμενα του αρχικού αντικειμένου στο νέο πεδίο προς πεδίο.
 </WRAP> </WRAP>
  
-Μία άλλη περίπτωση κατά την οποία θα κληθεί o κατασκευαστής αντιγραφέας είναι η παρακάτω. Εδώ μαζί με την δήλωση της μεταβλητής καλείται ο κατασκευαστής αντιγραφέας του //r1// με όρισμα το //r2//. +Μία άλλη περίπτωση κατά την οποία θα κληθεί o κατασκευαστής αντιγραφέας είναι η παρακάτω. Εδώ η δήλωση της μεταβλητής r2 συμπίπτει με την αρχικοποίηση του αντικειμένου. Σε αυτή την περίπτωση καλείται ο κατασκευαστής αντιγραφέας με όρισμα το //r1//. 
  
 <code cpp CopyRectangle.cpp> <code cpp CopyRectangle.cpp>
Line 103: Line 109:
 } }
 </code> </code>
-Για τον μεταγλωττιστή όμως οι κώδικες είναι διαφορετικοί. Στην πρώτη περίπτωση καλείται ο κατασκευαστής αντιγραφέας (//copy constructor//), ενώ στη 2η περίπτωση καλείται ο //default// κατασκευαστής και στη συνέχεια γίνεται ανάθεση των τιμών των πεδίων του //r1// στα πεδία του //r2//.+Για τον μεταγλωττιστή όμως οι κώδικες είναι διαφορετικοί. Στην πρώτη περίπτωση καλείται ο κατασκευαστής αντιγραφέας (//copy constructor//), ενώ στη 2η περίπτωση καλείται ο //default// κατασκευαστής και στη συνέχεια γίνεται ανάθεση των τιμών των πεδίων του //r1// στα πεδία του //r2// (πεδίο προς πεδίο).
 </WRAP> </WRAP>
  
Line 153: Line 159:
     int getWidth();     int getWidth();
     int getHeight();     int getHeight();
-    void setOrigin(Point *p) { origin = p} +    void setOrigin(Point *p); 
-    Point *getOrigin() { return origin}+    Point *getOrigin();
 }; };
  
Line 198: Line 204:
  
 <code cpp MoveOrigin.cpp> <code cpp MoveOrigin.cpp>
- 
 #include "Rectangle.cpp" #include "Rectangle.cpp"
  
Line 216: Line 221:
 </code> </code>
  
-Ο παραπάνω κώδικας αντιγράφει στο αντικείμενο //r2// τα πεδία του αντικειμένου //r1// πεδίο προς πεδίο. Αυτό σημαίνει ότι τα αντικείμενα //r1// και //r2// μοιράζονται το ίδιο αντικείμενο τύπου //Point//. Εάν μεταβληθούν οι συντεταγμένες του //Point// από το αντικείμενο //r1//, η μεταβολή θα ισχύει και για το αντικείμενο //r2//Εάν θέλετε να αποφύγετε αυτή τη συμπεριφορά θα πρέπει να ορίσετε τον δικό σας κατασκευαστή αντιγραφέα που κάνει τα εξής:+Ο παραπάνω κώδικας αντιγράφει στο αντικείμενο //r2// τα πεδία του αντικειμένου //r1// πεδίο προς πεδίο. Αυτό σημαίνει ότι τα αντικείμενα //r1// και //r2// μοιράζονται το ίδιο αντικείμενο τύπου //Point//Ισχύουν επομένως τα εξής: 
 +  * Εάν μεταβληθούν οι συντεταγμένες του //Point// από το αντικείμενο //r1//, η μεταβολή θα ισχύει και για το αντικείμενο //r2// 
 +  * Κατά την έξοδο από τη συνάρτηση main, το αντικείμενο //r1// θα καταστραφεί ελευθερώνοντας τη δεσμευμένη μνήμη για το πεδίο του //origin//. Η προσπάθεια καταστρροφής του αντικειμένου //r2// θα οδηγήσει σε σφάλμα διότι θα προσπαθήσει να ελευθερώσει μία περιοχή μνήμης που έχει ήδη ελευθερωθεί κατά την καταστροφή του //r1//. Το σφάλμα που εκτυπώνεται όταν το πρόγραμμα εκτελεστεί είναι το εξής: 
 + 
 +<code> 
 +*** Error in `./a.out': double free or corruption (fasttop): 0x00000000006d6010 *** 
 +Ακυρώθηκε (core dumped) 
 +</code> 
 + 
 +Για να αποφύγετε την παραπάνω συμπεριφορά θα πρέπει να ορίσετε τον δικό σας κατασκευαστή αντιγραφέα που κάνει τα εξής:
   - Δημιουργεί ένα νέο αντικείμενο τύπου //Point//.   - Δημιουργεί ένα νέο αντικείμενο τύπου //Point//.
-  - Αντιγράφει τα περιεχόμενα του παλιού στο νέο.+  - Αντιγράφει τα περιεχόμενα του παλιού αντικειμένου στο νέο.
  
 Ο προτεινόμενος κατασκευαστής αντιγραφέας δίνεται παρακάτω: Ο προτεινόμενος κατασκευαστής αντιγραφέας δίνεται παρακάτω:
cpp/copy_constructors.txt · Last modified: 2022/05/12 19:41 by gthanos