Καθοριζόμενοι τελεστές

Διομήδης Σπινέλλης
Τμήμα Διοικητικής Επιστήμης και Τεχνολογίας
Οικονομικό Πανεπιστήμιο Αθηνών
dds@aueb.gr

Καθοριζόμενοι τελεστές

Παράδειγμα: ασφαλείς πίνακες

Στη 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);
        intoperator[](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(2362000);           // Create a new date
        cout << dt;                     // Output the date
        return 0;
}

Ασκήσεις

Άσκηση 3 (προαιρετική)

  1. Να υλοποιηθεί σε C++ μια κλάση που να υποστηρίζει πράξεις μεταξύ μιγαδικών αριθμών. Με τη βοήθεια της κλάσης αυτής να υλοποιήσετε μια αριθμομηχανή που να υποστηρίζει μιγαδικούς αριθμούς.