Όταν δηλώνεται ένα αντικείμενο ως const (όπως παρακάτω), τότε τα πεδία του αντικειμένου μπορούν μόνο να διαβαστούν αλλά όχι να μεταβληθούν, πρόκειται δηλαδή για ένα αμετάβλητο αντικείμενο. Εξαίρεση αποτελεί ο κατασκευαστής του αντικειμένου, ο οποίος αρχικοποιεί κανονικά το αντικείμενο και μεταβάλλει τις μεταβλητές του.
#include <iostream> using namespace std; class Rectangle { private: int width, height; public: Rectangle(int width, int height); void setWidth(int width); void setHeight(int height); int getWidth(); int getHeight(); }; Rectangle::Rectangle(int width, int 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() { return width; } int Rectangle::getHeight() { return height; } int main() { const Rectangle rect(10,5); }
Στον παραπάνω κώδικα επιχειρήστε να διαβάσετε την μεταβλητή width, ως εξής:
int main() { const Rectangle rect(10,5); cout << rect.getWidth(); }
Σε αυτή την περίπτωση λαμβάνετε το παρακάτω μήνυμα λάθους από το μεγαγλωττιστή:
Rectangle5.cpp: In function ‘int main()’: Rectangle5.cpp:26:25: error: passing ‘const Rectangle’ as ‘this’ argument of ‘int Rectangle::getWidth()’ discards qualifiers [-fpermissive] cout << rect.getWidth(); ^
Η επεξήγηση του παραπάνω μηνύματος είναι ότι εφόσον το αντικείμενο είναι const θα πρέπει και η μέθοδοι που χρησιμοποιούμε για να προσπελάσουμε το αντικείμενο να είναι const, δηλαδή να δηλώνουν ότι δεν μεταβάλλουν το αντικείμενο κατά την εκτέλεση τους. Ο διορθωμένος κώδικας δηλώνει τις συναρτήσεις getWidth και getHeight ως const και έχει ως εξής:
#include <iostream> using namespace std; 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; }; Rectangle::Rectangle(int width, int 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; } int main() { const Rectangle rect(10,5); cout << rect.getWidth(); }
Στον παραπάνω κώδικα μπορείτε να έχετε δύο εκδόσεις για τις συναρτήσεις getWidth() και getHeight() μία που εφαρμόζεται σε const και μία που εφαρμόζεται σε non-const αντικείμενα ως εξής:
#include <iostream> using namespace std; 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; int getWidth() ; int getHeight(); }; Rectangle::Rectangle(int width, int 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 { 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; } int main() { const Rectangle rect1(10,5); Rectangle rect2(10,5); cout << "rect1 width: " << rect1.getWidth() << endl; cout << "rect2 width: " << rect2.getWidth() << endl; }
Στο παραπάνω παράδειγμα, η ύπαρξη της non-const μεθόδου στο συγκεκριμένο παράδειγμα είναι πλεονασμός καθώς η const μέθοδος μπορεί να κληθεί και από non-const αντικείμενα. Όπως δείξαμε ο περιορισμός ισχύει μόνο κατά το αντίστροφο, δηλαδή ένα const αντικείμενο δεν μπορεί να καλέσει μία non-const μέθοδο.