Υπερφόρτωση μοναδιαίων τελεστών (unary operators)
Ο παρακάτω πίνακας περιγράφει την υπερφόρτωση των τελεστών στο παράδειγμα της κλάσης Vector που ακολουθεί.
Τελεστής | Θέση (πριν ή μετά το αντικείμενο) | Περιγραφή | Μεταβάλει το αντικείμενο* | Φιλική συνάρτηση |
---|---|---|---|---|
+ | Πριν | Επιστρέφει το άθροισμα των στοιχείων του αντικειμένου. | Όχι | Όχι |
- | Πριν | Επιστρέφει ένα νέο αντικείμενο τα στοιχεία του οποίου έχουν αντεστραμμένο πρόσημο σε σχέση με το αντικείμενο που εφαρμόζεται. | Όχι | Όχι |
++ | Πριν | Επιστρέφει μία αναφορά στο τρέχον αντικείμενο, τα στοιχεία του οποίου έχουν αυξηθεί κατά ένα. | Ναι | Όχι |
-- | Πριν | Επιστρέφει μία αναφορά στο αντικείμενο που περνιέται ως 1η παράμετρος στη φιλική συνάρτηση (δηλαδή το τρέχον αντικείμενο), τα στοιχεία του οποίου έχουν μειωθεί κατά ένα. | Ναι | Ναι |
++ | Μετά | Επιστρέφει ένα νέο αντικείμενο, που είναι αντίγραφο του αντικειμένου στο οποίο εφαρμόζεται ο τελεστής, πριν την πράξη της αύξησης. Το αντικείμενο στο οποίο εφαρμόζεται ο τελεστής αυξάνει τις τιμές των στοιχείων του κατά 1. | Ναι | Όχι |
-- | Μετά | Επιστρέφει ένα νέο αντικείμενο, που είναι αντίγραφο του αντικειμένου στο οποίο εφαρμόζεται ο τελεστής, πριν την πράξη της μείωσης. Το αντικείμενο στο οποίο εφαρμόζεται ο τελεστής μειώνει τις τιμές των στοιχείων του κατά 1. | Ναι | Ναι |
* | Πριν | Επιστρέφει έναν ακέραιο που αποτελεί το γινόμενο των στοιχείων του πίνακα. | Όχι | Όχι |
! | Πριν | Επιστρέφει ένα νέο αντικείμενο τα στοιχεία του οποίου έχουν αντίστροφη σειρά σε σχέση με το αντικείμενο που εφαρμόζεται. | Όχι | Ναι |
~ | Πριν | Επιστρέφει ένα νέο αντικείμενο τα στοιχεία του οποίου αποτελούν το binary NOT των στοιχείων του αντικειμένου στο οποίο εφαρμόζεται. | Όχι | Όχι |
* στο οποίο εφαρμόζεται.
Προκειμένου να μπορέσουμε να παρακολουθήσουμε την υπερφόρτωση των τελεστών υπερφορτώνουμε τον τελεστή =. Η επεξήγηση της υπερφόρτωσης του τελεστή = θα δοθεί στη συνέχεια.
Προσέξτε τη διαφορετική δήλωση της συνάρτησης υπερφόρτωσης ανάμεσα στους μοναδιαίους τελεστές αύξησης και μείωσης κατά ένα (++, --) όταν αυτοί εφαρμόζονται πριν και μετά το αντικείμενο (prefix και postfix operators)
Το prototype της συνάρτησης υπερφόρτωσης στην περίπτωση του prefix και postfix increment/decrement τελεστή έχει ως εξής. Στην περίπτωση δήλωσης του τελεστή πριν το αντικείμενο η δήλωση είναι
Vector operator++(); Vector operator--();
Στην περίπτωση δήλωσης του τελεστή μετά το αντικείμενο η δήλωση είναι
Vector operator++(int a); Vector operator--(int a);
Επίσης, παρατηρήστε ότι οι συναρτήσεις που δεν μεταβάλλουν το αντικείμενο στο οποίο εφαρμόζονται δηλώνονται ως const. Για παράδειγμα, η συνάρτηση
Vector operator~() const;
επιστρέφει ένα νέο αντικείμενο του οποίου τα στοιχεία είναι το binary NOT του αρχικού. Ο αρχικός πίνακας παραμένει αμετάβλητος.
- Vector.hpp
#include <iostream> #include <string> #include <cstdlib> using namespace std; #ifndef _VECTOR_HPP_ #define _VECTOR_HPP_ class Vector { int *array; int size; public: Vector(unsigned int length=0); Vector(const Vector &v); Vector(const Vector *v); ~Vector(); unsigned int length() const; // return Vector's length. int& valueAt(unsigned int pos); // return a reference to element at position pos int find(int a) const; // check if 'a' exists in Vector. Return the position // If found, return the position of the element. // Otherwise, return -1 void print() const; // print to standard output vector values void print(string &msg) const; // print to standard output msg and vector values Vector& operator=(const Vector &v); int operator+() const; // returns the sum of Vector elements friend int operator*(const Vector&) ; // returns the product of Vector elements Vector operator-() const; // returns a new Vector, containing the negative // values of the original vector. Vector& operator++(); // prefix increment. Returns reference to the existing vector. friend Vector& operator--(Vector&); // prefix decrement. Returns reference to the existing vector. Vector operator++(int ); // postfix increment. Returns a new Vector. friend Vector operator--(Vector&, int); // postfix decrement. Returns a new Vector. Vector operator~() const; // returns the binary NOT for each element in a new Vector friend Vector operator!(const Vector &v); // returns a copy of the Vector with // elements in inverted sequence. }; #endif
- Vector.cpp
#include "Vector.hpp" Vector::Vector(unsigned int length) { size = length; array = new (nothrow) int[size]; if(array==NULL) { cerr << "Memory allocation failure!" << endl; exit(-1); } for(int i=0; i<size; i++) array[i] = 0; } Vector::Vector(const Vector &v) { size = v.length(); array = new (nothrow) int[size]; if(array==NULL) { cerr << "Memory allocation failure!" << endl; exit(-1); } for(int i=0; i<size; i++) array[i] = v.array[i]; } Vector::Vector(const Vector *v) { size = v->length(); array = new (nothrow) int[size]; if(array==NULL) { cerr << "Memory allocation failure!" << endl; exit(-1); } for(int i=0; i<size; i++) array[i] = v->array[i]; } Vector::~Vector() { delete [] array; } unsigned int Vector::length() const { return size; } int& Vector::valueAt(unsigned int pos) { if(pos>=length()) { cerr << "Invalid position!\n"; return array[size-1]; } return array[pos]; } int Vector::find(int a) const { for(int i=0; i<size; i++) { if(array[i] == a) return i; } return -1; } void Vector::print() const { for(int i=0; i<size; i++) { cout << array[i]; if(i==size-1) cout << endl; else cout << ", "; } } void Vector::print(string &msg) const { cout << msg; print(); } Vector &Vector::operator=(const Vector &v) { if(array!=NULL) delete [] array; size = v.length(); array = new (nothrow) int[size]; if(array==NULL) { cerr << "Memory allocation failure!" << endl; exit(-1); } for(int i=0; i<size; i++) array[i] = v.array[i]; return *this; } int Vector::operator+() const{ int sum=0.0; for(int i=0; i<size; i++) { sum += array[i]; } return sum; } Vector Vector::operator-() const{ Vector v(size); for(int i=0; i<size; i++) { v.valueAt(i) = -array[i]; } return v; } //prefix increment Vector& Vector::operator++() { for(int i=0; i<size; i++) { array[i]++; } return *this; } //prefix decrement Vector& operator--(Vector& v) { for(int i=0; i<v.size; i++) { v.array[i]--; } return v; } int operator*(const Vector& v){ int product = 1; for(int i=0; i<v.size; i++) product *= v.array[i]; return product; } Vector Vector::operator~() const{ Vector v(size); for(int i=0; i<size; i++) v.valueAt(i) = ~array[i]; return v; } Vector operator!(const Vector &v) { Vector n = v; for(int i=0; i<v.size; i++) n.array[i] = v.array[v.size-1-i]; return n; } //postfix increment Vector Vector::operator++(int a) { Vector v(this); for(int i=0; i<size; i++) { array[i]++; } return v; } //postfix decrement Vector operator--(Vector& v, int a) { Vector w(v); for(int i=0; i<v.size; i++) { v.array[i]--; } return w; }
- VectorUsage.cpp
#include "Vector.hpp" int main() { Vector v(5); v.valueAt(0) = 2; v.valueAt(1) = 3; v.valueAt(2) = 4; v.valueAt(3) = 5; v.valueAt(4) = 6; string msg = "Initial Vector: "; v.print(msg); cout << "+v: " << +v << endl; Vector f = -v; f.print(msg="f = -v: "); cout << endl; cout << "*v: " << *v << endl; f = !v; f.print(msg = "f = !v: "); cout << endl; cout << "~2: "<< ~2 << " | ~3: "<< ~3 << " | ~4: "<< ~4 << endl; f = ~v; f.print(msg = "f = ~v: "); cout << endl; f = ++v; f.print(msg = "f = ++v: "); v.print(msg = "v: "); f = --v; f.print(msg = "f = --v: "); v.print(msg = "v: "); cout << endl; f = v++; f.print(msg = "f = v++: "); v.print(msg = "v: "); f = v--; f.print(msg = "f = v--: "); v.print(msg = "v: "); }