User Tools

Site Tools


cpp:const_member_functions

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
cpp:const_member_functions [2017/05/15 07:18] gthanoscpp:const_member_functions [Unknown date] (current) – external edit (Unknown date) 127.0.0.1
Line 1: Line 1:
 ====== Const μέθοδοι της κλάσης ====== ====== Const μέθοδοι της κλάσης ======
  
-Όταν δηλώνεται ένα αντικείμενο ως //const// (όπως παρακάτω), τότε οι μεταβλητές του αντικειμένου μπορούν μόνο να διαβαστούν αλλά όχι να μεταβληθούν, πρόκειται δηλαδή για ένα αμετάβλητο αντικείμενο. Εξαίρεση αποτελεί ο κατασκευαστής του αντικειμένου, ο οποίος αρχικοποιεί κανονικά το αντικείμενο και μεταβάλλει τις τιμές των μεταβλητών του. +Όταν δηλώνεται ένα αντικείμενο ως //const// (όπως παρακάτω), τότε τα πεδία του αντικειμένου μπορούν μόνο να διαβαστούν αλλά όχι να μεταβληθούν, πρόκειται δηλαδή για ένα αμετάβλητο αντικείμενο. Εξαίρεση αποτελεί ο κατασκευαστής του αντικειμένου, ο οποίος αρχικοποιεί κανονικά το αντικείμενο και μεταβάλλει τις μεταβλητές του.
- +
-<code cpp Point.cpp> +
-#include <iostream> +
-using namespace std; +
- +
-class Point { +
-    int x, y; +
-  public: +
-    Point(int vx,int vy) { x = vx; y = vy; }    +
-    void setX(int vx) { x = vx; } +
-    void setY(int vy) { y = vy; } +
-    int getX() { return x; } +
-    int getY() { return y; } +
-}; +
-</code>+
  
 <code cpp Rectangle.cpp> <code cpp Rectangle.cpp>
 #include <iostream> #include <iostream>
-#include <cstdlib> 
-#include <ctime> 
 using namespace std; using namespace std;
- 
-#include "Point.cpp" 
  
 class Rectangle { class Rectangle {
   private:   private:
     int width, height;     int width, height;
-    Point *origin; 
   public:   public:
-    Rectangle(int w, int h, Point p); +    Rectangle(int width, int height); 
-    Rectangle(int s, Point p); +    void setWidth(int width); 
-    Rectangle(); +    void setHeight(int height); 
-    ~Rectangle(); +    int getWidth(); 
-    void setOrigin(Point &p); +    int getHeight();
-    Point &getOrigin();+
 }; };
  
-Rectangle::Rectangle(int w, int h, Point p) { +Rectangle::Rectangle(int width, int height) { 
-  width = w; height = h; +  this->width = widththis->height = height;
-  origin = new (nothrow) Point( p.getX(), p.getY() ); +
-  if(origin == NULL) { +
-    cerr << "Memory allocation failure!\n"; +
-    exit(-1); +
-  }+
 } }
  
-Rectangle::~Rectangle() { +void Rectangle::setWidth(int width) { this->width = width; } 
-  delete origin; +void Rectangle::setHeight(int height) { this->height height} 
-} +int Rectangle::getWidth() { return width; } 
- +int Rectangle::getHeight() { return height; }
-void Rectangle::setOrigin(Point &p) {  +
-  if(origin!=NULL) +
-    delete origin+
-   +
-  origin = new (nothrow) Point( p.getX(), p.getY() ); +
-  if(origin == NULL) { +
-    cerr << "Memory allocation failure!\n"; +
-    exit(-1); +
-  +
-+
- +
-Point &Rectangle::getOrigin() { return *origin; }+
  
 int main() { int main() {
-  const Point p(5,6); +  const Rectangle rect(10,5);  
-  const Rectangle rect(1,2,p);+
 } }
 </code> </code>
  
-Στον παραπάνω κώδικα επιχειρήστε να διαβάσετε το πεδίο //origin//, ως εξής:+Στον παραπάνω κώδικα επιχειρήστε να διαβάσετε την μεταβλητή //width//, ως εξής:
  
 <code cpp> <code cpp>
 int main() { int main() {
-  const Point p(5,6); +  const Rectangle rect(10,5); 
-  const Rectangle rect(1,2,p); +  cout << rect.getWidth();
-  Point p1 = rect.getOrigin();+
 } }
 </code> </code>
  
-Σε αυτή την περίπτωση λαμβάνετε το παρακάτω μήνυμα λάθους:+Σε αυτή την περίπτωση λαμβάνετε το παρακάτω μήνυμα λάθους από το μεγαγλωττιστή:
 <code> <code>
-Rectangle.cpp: In function ‘int main()’: +Rectangle5.cpp: In function ‘int main()’:                                                                                                                                                                           
-Rectangle.cpp:46:35: error: passing ‘const Rectangle’ as ‘this’ argument of ‘Point& Rectangle::getOrigin()’ discards qualifiers [-fpermissive] +Rectangle5.cpp:26:25: error: passing ‘const Rectangle’ as ‘this’ argument of ‘int Rectangle::getWidth()’ discards qualifiers [-fpermissive]                                                                         
-   const Point p1 = rect.getOrigin(); +   cout << rect.getWidth();                                                                                                                                                                                         
-                                   ^+                         ^
 </code> </code>
  
-Η επεξήγηση του παραπάνω μηνύματος είναι ότι εφόσον το αντικείμενο είναι //const// θα πρέπει και οι μέθοδοι που χρησιμοποιούμε για να προσπελάσουμε το αντικείμενο να είναι δηλωμένες ως //const//, δηλαδή να δηλώνουν ότι δεν μεταβάλλουν το αντικείμενο κατά την εκτέλεση τους. Ο διορθωμένος κώδικας δηλώνει ως //const// τη συνάρτηση //getOrigin// και έχει ως εξής:+Η επεξήγηση του παραπάνω μηνύματος είναι ότι εφόσον το αντικείμενο είναι //const// θα πρέπει και η μέθοδοι που χρησιμοποιούμε για να προσπελάσουμε το αντικείμενο να είναι const, δηλαδή να δηλώνουν ότι δεν μεταβάλλουν το αντικείμενο κατά την εκτέλεση τους. Ο διορθωμένος κώδικας δηλώνει τις συναρτήσεις  //getWidth// και //getHeight// ως //const// και έχει ως εξής:
  
-<code cpp> +<code cpp Rectangle.cpp> 
-Point &Rectangle::getOrigin() const { return *origin; } +#include <iostream> 
-</code>+using namespace std;
  
-===== Επιστρεφόμενη τιμή const συναρτήσεων =====+class Rectangle { 
 +  private: 
 +    int width, height; 
 +  public: 
 +    Rectangle(int width, int height); 
 +    void setWidth(int width); 
 +    void setHeight(int height); 
 +    int getWidth() const
 +    int getHeight() const; 
 +};
  
-Στον παραπάνω κώδικα αν και η συνάρτηση //getOrigin// δεν μεταβάλλει το αντικείμενο κατά την κλάση τηςτο αντικείμενο μπορεί να μεταβληθεί αμέσως μετά την κλήση αυτής ως εξής:+Rectangle::Rectangle(int widthint height) { 
 +  this->width = width; this->height = height; 
 +
 + 
 +void Rectangle::setWidth(int width) { this->width = width; } 
 +void Rectangle::setHeight(int height) { this->height = height; } 
 +int Rectangle::getWidth() const { return width; } 
 +int Rectangle::getHeight() const { return height; }
  
-<code cpp> 
 int main() { int main() {
-  const Point p(5,6); +  const Rectangle rect(10,5); 
-  const Rectangle rect(1,2,p); +  cout << rect.getWidth();
-  Point p1 = rect.getOrigin(); +
-  p1.setX(p1.getX()+1);+
 } }
-<code cpp>+</code> 
 + 
 +===== Υπερφόρτωση const και non-const συναρτήσεων =====
  
-Για να αποφύγουμε τα παραπάνω πρόβληματα είναι καλό να δηλώσουμε την επιστρεφόμενη τιμή της getOrigin ως //const//. Σε αυτή την περίπτωση η επιστρεφόμενη τιμή θα πρέπει με τη σειρά της να ανατεθεί σε ένα αντικείμενο τύπου const. Ο συνολικός κώδικας έχει ως εξής:+Στον παραπάνω κώδικα μπορείτε να έχετε δύο εκδόσεις για τις συναρτήσεις getWidth() και getHeight() μία που εφαρμόζεται σε const και μία που εφαρμόζεται σε non-const αντικείμενα ως εξής:
  
 <code cpp Rectangle.cpp> <code cpp Rectangle.cpp>
 #include <iostream> #include <iostream>
-#include <cstdlib> 
-#include <ctime> 
 using namespace std; using namespace std;
- 
-#include "Point.cpp" 
  
 class Rectangle { class Rectangle {
   private:   private:
     int width, height;     int width, height;
-    Point *origin; 
   public:   public:
-    Rectangle(int w, int h, Point p); +    Rectangle(int width, int height); 
-    Rectangle(int s, Point p); +    void setWidth(int width); 
-    Rectangle(); +    void setHeight(int height); 
-    ~Rectangle(); +    int getWidth() const
-    void setOrigin(Point &p); +    int getHeight() const
-    const Point &getOrigin() const;+    int getWidth() ; 
 +    int getHeight();
 }; };
  
-Rectangle::Rectangle(int w, int h, Point p) { +Rectangle::Rectangle(int width, int height) { 
-  width = w; height = h; +  this->width = widththis->height = height;
-  origin = new (nothrow) Point( p.getX(), p.getY() ); +
-  if(origin == NULL) { +
-    cerr << "Memory allocation failure!\n"; +
-    exit(-1); +
-  }+
 } }
  
-Rectangle::~Rectangle() { +void Rectangle::setWidth(int width) { this->width = width; } 
-  delete origin+void Rectangle::setHeight(int height) { this->height = height; } 
-}+int Rectangle::getWidth() const { cout << "I am the const method\n"return width; } 
 +int Rectangle::getHeight() const { return height; } 
 +int Rectangle::getWidth() { cout << "I am the non-const method\n"; return width; } 
 +int Rectangle::getHeight() { return height; }
  
-void Rectangle::setOrigin(Point &p) {  +int main() { 
-  if(origin!=NULL) +  const Rectangle rect1(10,5); 
-    delete origin+  Rectangle rect2(10,5); 
-   +  cout << "rect1 width: " << rect1.getWidth() << endl; 
-  origin = new (nothrow) Point( p.getX()p.getY() ); +  cout << "rect2 width: << rect2.getWidth() << endl;
-  if(origin == NULL{ +
-    cerr << "Memory allocation failure!\n"+
-    exit(-1); +
-  }+
 } }
 +</code>
 +
 +<WRAP center round tip 80%>
 +Στο παραπάνω παράδειγμα, η ύπαρξη της //non-const// μεθόδου στο συγκεκριμένο παράδειγμα είναι πλεονασμός καθώς η //const// μέθοδος μπορεί να κληθεί και από //non-const// αντικείμενα. Όπως δείξαμε ο περιορισμός ισχύει μόνο κατά το αντίστροφο, δηλαδή ένα //const// αντικείμενο δεν μπορεί να καλέσει μία //non-const// μέθοδο.
 +</WRAP>
 +
  
-const Point &Rectangle::getOrigin() const { return *origin; } 
  
-int main() { 
-  const Point p(5,6); 
-  const Rectangle rect(1,2,p); 
-  const Point p1 = rect.getOrigin(); 
-} 
-</code> 
-int main() { 
-  const Point p(5,6); 
-  const Rectangle rect(1,2,p); 
-  const Point p1 = rect.getOrigin(); 
-} 
-</code> 
-<code> 
  
cpp/const_member_functions.1494832721.txt.gz · Last modified: 2017/05/15 06:18 (external edit)