User Tools

Site Tools


cpp:const_member_functions

This is an old revision of the document!


Const μέθοδοι της κλάσης

Όταν δηλώνεται ένα αντικείμενο ως const (όπως παρακάτω), τότε οι μεταβλητές του αντικειμένου μπορούν μόνο να διαβαστούν αλλά όχι να μεταβληθούν, πρόκειται δηλαδή για ένα αμετάβλητο αντικείμενο. Εξαίρεση αποτελεί ο κατασκευαστής του αντικειμένου, ο οποίος αρχικοποιεί κανονικά το αντικείμενο και μεταβάλλει τις τιμές των μεταβλητών του.

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; }
};
Rectangle.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
 
#include "Point.cpp"
 
class Rectangle {
  private:
    int width, height;
    Point *origin;
  public:
    Rectangle(int w, int h, Point p);
    Rectangle(int s, Point p);
    Rectangle();
    ~Rectangle();
    void setOrigin(Point &p);
    Point &getOrigin();
};
 
Rectangle::Rectangle(int w, int h, Point p) {
  width = w; height = h;
  origin = new (nothrow) Point( p.getX(), p.getY() );
  if(origin == NULL) {
    cerr << "Memory allocation failure!\n";
    exit(-1);
  }
}
 
Rectangle::~Rectangle() {
  delete origin;
}
 
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() {
  const Point p(5,6);
  const Rectangle rect(1,2,p);
}

Στον παραπάνω κώδικα επιχειρήστε να διαβάσετε το πεδίο origin, ως εξής:

int main() {
  const Point p(5,6);
  const Rectangle rect(1,2,p);
  Point p1 = rect.getOrigin();
}

Σε αυτή την περίπτωση λαμβάνετε το παρακάτω μήνυμα λάθους:

Rectangle.cpp: In function ‘int main()’:
Rectangle.cpp:46:35: error: passing ‘const Rectangle’ as ‘this’ argument of ‘Point& Rectangle::getOrigin()’ discards qualifiers [-fpermissive]
   const Point p1 = rect.getOrigin();
                                   ^

Η επεξήγηση του παραπάνω μηνύματος είναι ότι εφόσον το αντικείμενο είναι const θα πρέπει και οι μέθοδοι που χρησιμοποιούμε για να προσπελάσουμε το αντικείμενο να είναι δηλωμένες ως const, δηλαδή να δηλώνουν ότι δεν μεταβάλλουν το αντικείμενο κατά την εκτέλεση τους. Ο διορθωμένος κώδικας δηλώνει ως const τη συνάρτηση getOrigin και έχει ως εξής:

Point &Rectangle::getOrigin() const { return *origin; }

Επιστρεφόμενη τιμή const συναρτήσεων

Στον παραπάνω κώδικα αν και η συνάρτηση getOrigin δεν μεταβάλλει το αντικείμενο κατά την κλάση της, το αντικείμενο μπορεί να μεταβληθεί αμέσως μετά την κλήση αυτής ως εξής:

int main() {
  const Point p(5,6);
  const Rectangle rect(1,2,p);
  Point p1 = rect.getOrigin();
  p1.setX(p1.getX()+1);
}
<code cpp>
 
Για να αποφύγουμε τα παραπάνω πρόβληματα είναι καλό να δηλώσουμε την επιστρεφόμενη τιμή της getOrigin ως //const//. Σε αυτή την περίπτωση η επιστρεφόμενη τιμή θα πρέπει με τη σειρά της να ανατεθεί σε ένα αντικείμενο τύπου const. Ο συνολικός κώδικας έχει ως εξής:
 
<code cpp Rectangle.cpp>
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
 
#include "Point.cpp"
 
class Rectangle {
  private:
    int width, height;
    Point *origin;
  public:
    Rectangle(int w, int h, Point p);
    Rectangle(int s, Point p);
    Rectangle();
    ~Rectangle();
    void setOrigin(Point &p);
    const Point &getOrigin() const;
};
 
Rectangle::Rectangle(int w, int h, Point p) {
  width = w; height = h;
  origin = new (nothrow) Point( p.getX(), p.getY() );
  if(origin == NULL) {
    cerr << "Memory allocation failure!\n";
    exit(-1);
  }
}
 
Rectangle::~Rectangle() {
  delete origin;
}
 
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);
  }
}
 
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();
}

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)