Καθοριζόμενοι τελεστές
Διομήδης Σπινέλλης
Τμήμα Διοικητικής Επιστήμης και Τεχνολογίας
Οικονομικό Πανεπιστήμιο Αθηνών
dds@aueb.gr
Καθοριζόμενοι τελεστές
- Σε μια κλάση μπορούμε να ορίσουμε συναρτήσεις σε αντιστοιχία με
τους καθορισμένους τελεστές της C++ (+, -, *, /, ==, =, κ.λπ.)
με τη σύνταξη operator τελεστής(όρισμα).
- Το όρισμα πρέπει να περιέχει τόσες παραμέτρους όσες απαιτεί και
ο αντίστοιχος τελεστής. Αν η συνάρτηση είναι μέλος της κλάσης (και
όχι ορισμένη ως friend) τότε το πρώτο στοιχείο του ορίσματος περνάει
αυτόματα μέσω της this και δεν ορίζεται.
- Οι τελεστές που επιτρέπεται να οριστούν,
η προτεραιότητα των τελεστών και ο τρόπος που αυτοί συνδέονται
(αριστερά προς τα δεξιά ή ανάποδα) δεν μπορούν να μεταβληθούν.
- Το παρακάτω παράδειγμα ορίζει τον τελεστή + στην κλάση point,
επιτρέποντας την πρόσθεση σημείων:
#include <iostream.h>
class point {
private:
int x, y;
public:
point(int sx, int sy); // Constructor
point operator+(point b); // Overload the + operator
void display(); // Display member function
};
point::point(int sx, int sy)
{
x = sx;
y = sy;
}
void
point::display()
{
cout << "(" << x << "," << y << ")\n";
}
point
point::operator+(point b)
{
point p(x, y); // p is a new point at x, y
p.x += b.x;
p.y += b.y;
return (p);
}
main()
{
point p1 = point(1, 2);
point p2 = point(10, 20);
point p3 = point(0, 0);
p3 = p1 + p2;
p1.display();
p2.display();
p3.display();
}
Παράδειγμα: ασφαλείς πίνακες
Στη C και τη C++
οι δείκτες ενός πίνακα δεν ελέγχονται αν είναι συμβατοί με τις διαστάσεις
του πίνακα.
Έτσι το παρακάτω παράδειγμα δε θα εμφανίσει κάποιο λάθος κατά τη μεταγλώττιση
ή (πιθανά) και την εκτέλεση:
int a[20];
main()
{
a[50] = 42; // Out of bounds index
}
Το αποτέλεσμα είναι πως το παραπάνω πρόγραμμα μπορεί να γράψει σε θέσεις
μνήμης που φυλάσσονται άλλες μεταβλητές δημιουργώντας λάθη που είναι δύσκολο
να βρεθούν.
Στο επόμενο παράδειγμα, με τη χρήση καθοριζόμενων τελεστών, ορίζουμε την
κλάση intarray που υλοποιεί πίνακες ακεραίων μιας διάστασης.
Τα αντικείμενα της κλάσης αυτής μοιάζουν στη συμπεριφορά με πίνακες,
αλλά ελέγχουν αν ο δείκτης του πίνακα είναι συμβατός με τη διάσταση με την
οποία έχει οριστεί ο πίνακας.
#include <iostream.h>
#include <stdlib.h>
class intarray {
public:
intarray(unsigned int ssize = 10);
intarray(const intarray& sa);
~intarray(void);
intarray& operator=(const intarray& sa);
int& operator[](unsigned int i);
int elemnum();
protected:
unsigned int size; // Number of elements
int *values; // Values
};
intarray::intarray(unsigned int ssize)
{
size = ssize;
values = new int[ssize];
}
intarray::intarray(const intarray& sa)
{
size = sa.size;
values = new int[sa.size];
for (int i = 0; i < sa.size; i++)
values[i] = sa.values[i];
}
intarray::~intarray(void)
{
delete[] values;
}
intarray&
intarray::operator=(const intarray& sa)
{
delete values;
size = sa.size;
values = new int[size];
for (unsigned int i = 0; i < size; i++)
values[i] = sa.values[i];
return (*this);
}
int&
intarray::operator[](unsigned int i)
{
if (i >= size) {
cerr << "Array index " << i << " out of bounds\n";
exit(1);
}
return (values[i]);
}
int
intarray::elemnum()
{
return (size);
}
main()
{
intarray a(5);
a[2] = 8;
intarray b = a;
cout << b[2] << "\n"; // Will print 8
b[23] = 4; // Will exit with an error
return (0);
}
Είσοδος και έξοδος με τελεστές
Με καθορισμό μεθόδων για τους τελεστές << και >> μπορούμε να
ορίσουμε τον τρόπο που θα γίνεται η είσοδος και έξοδος για κλάσεις που ορίζουμε
εμείς.
Το παρακάτω παράδειγμα ορίζει μια κλάση date και τον τρόπο που αντικείμενα
της κλάσης αυτής θα εμφανίζονται στην οθόνη (ο ορισμός με τη
χρήση friend επιτρέπει στη συνάρτηση operator << να έχει ως πρώτο ορίσμα
μεταβλητή τύπου ostream).
#include <iostream.h>
class date {
private:
int month;
int day;
int year;
public:
date(int d, int m, int y);
friend ostream& operator<< (ostream& os, date& dt);
};
// Constructor
date::date(int d, int m, int y)
{
day = d;
month = m;
year = y;
}
// Overload << to define output
ostream& operator<< ( ostream& os, date& dt )
{
os << dt.day << '-' << dt.month << '-' << dt.year;
return os;
}
int
main()
{
date dt(23, 6, 2000); // Create a new date
cout << dt; // Output the date
return 0;
}
Ασκήσεις
Άσκηση 3 (προαιρετική)
- Να υλοποιηθεί σε C++ μια κλάση που να υποστηρίζει
πράξεις μεταξύ μιγαδικών αριθμών.
Με τη βοήθεια της κλάσης αυτής να υλοποιήσετε
μια αριθμομηχανή που να υποστηρίζει μιγαδικούς αριθμούς.