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 [2019/04/19 09:37] – [Ορισμός ενός κατασκευαστή αντιγραφέα] gthanoscpp:copy_constructors [2019/04/19 10:01] – [Μια πιο σύνθετη περίπτωση] gthanos
Line 40: Line 40:
 Στη 2η περίπτωση, η μεταβλητή //r// δηλώνεται ως //const// διότι κατά την εκτέλεση του κατασκευαστή αντιγραφέα το αντικείμενο //r// δεν μεταβάλλεται. Συνολικά η κλάση //Rectangle// διαμορφώνεται ως εξής: Στη 2η περίπτωση, η μεταβλητή //r// δηλώνεται ως //const// διότι κατά την εκτέλεση του κατασκευαστή αντιγραφέα το αντικείμενο //r// δεν μεταβάλλεται. Συνολικά η κλάση //Rectangle// διαμορφώνεται ως εξής:
  
-<code cpp Rectangle.cpp>+<code cpp Rectangle.hpp>
 #include <iostream> #include <iostream>
 #include <cstdlib> #include <cstdlib>
Line 53: Line 53:
     Rectangle(int s);     Rectangle(int s);
     Rectangle();     Rectangle();
 +    Rectangle(Rectangle &r);
     void setWidth(int w);     void setWidth(int w);
     void setHeight(int h);     void setHeight(int h);
Line 60: Line 61:
  
 Rectangle::Rectangle(int w, int h) { Rectangle::Rectangle(int w, int h) {
 +  cout << "Calling 2 args constructor" << endl;
   width = w; height = h;   width = w; height = h;
 } }
  
-Rectangle::Rectangle(int s) { +Rectangle::Rectangle(int s) : Rectangle(s,s) { 
-  width = s; height = s;+  cout << "Calling 1 args constructor" << endl;
 } }
  
-Rectangle::Rectangle() +Rectangle::Rectangle() : Rectangle(0,0{ 
-  srand(time(NULL)); +  cout << "Calling default constructor" << endl;
-  width = rand() % 10 + 1; height = rand() % 10 + 1;+
 } }
  
-// copy constructor 
 Rectangle::Rectangle(Rectangle &r) { Rectangle::Rectangle(Rectangle &r) {
 +  cout << "Calling copy constructor" << endl;
   width = r.width; height = r.height;   width = r.width; height = r.height;
 } }
Line 81: Line 82:
 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>
  
 <WRAP center round tip 80%> <WRAP center round tip 80%>
-Εάν δεν ορίσετε ένα δικό σας κατασκευαστή αντιγραφέα ο //compiler// δημιουργεί τον //default copy constructor//. Ο //default// αντιγράφει τα περιεχόμενα του αρχικού αντικειμένου στο νέο πεδίο προς πεδίο.+Εάν δεν ορίσετε ένα δικό σας κατασκευαστή αντιγραφέα ο //compiler// δημιουργεί τον //default copy constructor//. Ο //default// αντιγράφει τα περιεχόμενα του αντικειμένου που δίνεται ως όρισμα στο νέο αντικείμενο πεδίο προς πεδίο.
 </WRAP> </WRAP>
 +
 +==== Άλλη περίπτωση κλήση Copy Constructor ====
  
 Μία άλλη περίπτωση κατά την οποία θα κληθεί o κατασκευαστής αντιγραφέας είναι η παρακάτω. Εδώ η δήλωση της μεταβλητής r2 συμπίπτει με την αρχικοποίηση του αντικειμένου. Σε αυτή την περίπτωση καλείται ο κατασκευαστής αντιγραφέας με όρισμα το //r1// Μία άλλη περίπτωση κατά την οποία θα κληθεί o κατασκευαστής αντιγραφέας είναι η παρακάτω. Εδώ η δήλωση της μεταβλητής r2 συμπίπτει με την αρχικοποίηση του αντικειμένου. Σε αυτή την περίπτωση καλείται ο κατασκευαστής αντιγραφέας με όρισμα το //r1//
Line 112: Line 119:
 </WRAP> </WRAP>
  
-===== Δημιουργία κατασκευαστών αντιγραφέων =====+===== Μια πιο σύνθετη περίπτωση =====
  
-Στις περιπτώσεις που υπάρχουν πεδία δείκτες που δείχνουν σε άλλα αντικείμενα (στατικά ή δυναμικά δεσμευμένα) αντιγράφονται οι διευθύνσεις αυτές, όπως θα αντιγράφονταν οποιοδήποτε άλλο πεδίο. Αυτό πρακτικά σημαίνει ότι δύο ή περισσότερα αντικείμενα δείχνουν σε μία κοινή περιοχή μνήμης. Το παραπάνω μπορεί να προκαλέσει δυσλειτουργίες καθώς η μεταβολή του κοινού αντικειμένου επηρεάζει το σύνολο των αντικειμένων που το μοιράζονται.+Στις περιπτώσεις που υπάρχουν πεδία δείκτες που δείχνουν σε άλλα αντικείμενα (στατικά ή δυναμικά δεσμευμένα) αντιγράφονται οι διευθύνσεις αυτές, όπως θα αντιγράφονταν οποιοδήποτε άλλο πεδίο. Αυτό πρακτικά σημαίνει ότι δύο ή περισσότερα αντικείμενα δείχνουν σε μία κοινή περιοχή μνήμης. Το παραπάνω μπορεί να προκαλέσει δυσλειτουργίεςκαθώς η μεταβολή του κοινού αντικειμένου επηρεάζει το σύνολο των αντικειμένων που το μοιράζονται.
  
 Στο παρακάτω παράδειγμα ορίζουμε την κλάση //Point// η οποία αντιπροσωπεύει ένα σημείο στο διδιάστατο χώρο. Στο παρακάτω παράδειγμα ορίζουμε την κλάση //Point// η οποία αντιπροσωπεύει ένα σημείο στο διδιάστατο χώρο.
  
-<code cpp Point.cpp>+<code cpp Point.hpp>
 #include <iostream> #include <iostream>
 using namespace std; using namespace std;
Line 125: Line 132:
     int x, y;     int x, y;
   public:   public:
-    Point(int vx,int vy) { x = vx; y = vy; cout << "Point regular constructor!\n";+    Point(int vx,int vy) {  
-    Point(const Point &p) { x = p.x; y = p.y; cout << "Point copy constructor!\n";      +      x = vx; y = vy;  
-    Point() { cout << "Point default constructor!\n";+      cout << "Point regular constructor!\n"; 
-    ~Point() { cout << "xP Point destructor!\n"; }+    } 
 +     
 +    Point(const Point &p) {  
 +      x = p.x; y = p.y;  
 +      cout << "Point copy constructor!\n"; 
 +    } 
 +     
 +    Point() {  
 +      cout << "Point default constructor!\n"; 
 +    
 +    ~Point() {  
 +      cout << "xP Point destructor!\n";  
 +    } 
 +    
     void setX(int vx) { x = vx; }     void setX(int vx) { x = vx; }
     void setY(int vy) { y = vy; }     void setY(int vy) { y = vy; }
Line 138: Line 158:
 Η κλάση //Rectangle// που ακολουθεί ορίζει ένα πεδίο δείκτη σε αντικείμενα τύπου //Point//. Η δημιουργία ενός αντικειμένου τύπου //Rectangle// συνεπάγεται τη δυναμική δέσμευση μνήμης για το αντικείμενο τύπου //Point// που αυτή περιέχει. Δείτε το παράδειγμα που ακολουθεί. Η κλάση //Rectangle// που ακολουθεί ορίζει ένα πεδίο δείκτη σε αντικείμενα τύπου //Point//. Η δημιουργία ενός αντικειμένου τύπου //Rectangle// συνεπάγεται τη δυναμική δέσμευση μνήμης για το αντικείμενο τύπου //Point// που αυτή περιέχει. Δείτε το παράδειγμα που ακολουθεί.
  
-<code cpp Rectangle.cpp>+<code cpp Rectangle.hpp>
 #include <iostream> #include <iostream>
 #include <cstdlib> #include <cstdlib>
Line 144: Line 164:
 using namespace std; using namespace std;
  
-#include "Point.cpp"+#include "Point.hpp"
  
 class Rectangle { class Rectangle {
Line 155: Line 175:
     Rectangle();     Rectangle();
     ~Rectangle();     ~Rectangle();
 +    Rectangle(Rectangle &r);
     void setWidth(int w);     void setWidth(int w);
     void setHeight(int h);     void setHeight(int h);
Line 170: Line 191:
     exit(-1);     exit(-1);
   }   }
 +  cout << "Calling 2 args constructor" << endl;
 } }
  
-Rectangle::Rectangle(int s, Point p) +Rectangle::Rectangle(int s, Point p) : Rectangle(s,s,p) { 
-  width = s; height = s+  cout << "Calling 1 args constructor<< endl;
-  origin = new (nothrow) Point( p.getX(), p.getY(); +
-  if(origin == NULL) { +
-    cerr << "Memory allocation failure!\n"; +
-    exit(-1); +
-  }+
 } }
  
-Rectangle::Rectangle() +Rectangle::Rectangle() : Rectangle(0,Point()) { 
-  srand(time(NULL))+  cout << "Calling 0 args constructor<< endl;
-  width = rand() % 10 + 1; height = rand() % 10 + 1; +
-  origin = new (nothrow) Point{}; +
-  if(origin == NULL) { +
-    cerr << "Memory allocation failure!\n"; +
-    exit(-1); +
-  }+
 } }
  
Line 204: Line 215:
  
 <code cpp MoveOrigin.cpp> <code cpp MoveOrigin.cpp>
-#include "Rectangle.cpp"+#include "Rectangle.hpp"
  
 int moveOrigin(Rectangle &r, int dx, int dy) { int moveOrigin(Rectangle &r, int dx, int dy) {
Line 239: Line 250:
   width = r.width;   width = r.width;
   height = r.height;   height = r.height;
-  origin = new (nothrow) Point(r.getOrigin()->getX(), r.getOrigin()->getY()); +  if(r.origin == nullptr) 
-  if(origin == NULL) { +    origin = nullptr; 
-    cerr << "Memory allocation failure!"; +  else { 
-    exit(-1);+    origin = new (nothrow) Point(r.getOrigin()->getX(), r.getOrigin()->getY()); 
 +    if(origin == NULL) { 
 +      cerr << "Memory allocation failure!"; 
 +      exit(-1); 
 +    }
   }   }
 } }
cpp/copy_constructors.txt · Last modified: 2022/05/12 19:41 by gthanos