User Tools

Site Tools


cpp:operator_overloading

This is an old revision of the document!


Υπερφόρτωση τελεστών

Η C++ επιτρέπει την υπεφόρτωση των περισσότερων από τους διαθέσιμους τελεστές της γλώσσας. Με τον όρο υπεφόρτωση εννοούμε τον ορισμό μιας νέας συμπεριφοράς για τον τελεστή όταν αυτός εφαρμόζεται όχι σε βασικούς τύπους δεδομένων, αλλά σε αναφορικούς τύπους δεδομένων. Για παράδειγμα, στην παρακάτω κλάση Time τι θα γίνει εάν προσθέσουμε δύο αντικείμενα της κλάσης αυτής;

Time.cpp
class Time {
  int minutes;
  int hours;
public:
  Time(int hours, int minutes) {
    if(hours >= 0)
      this->hours = hours;
    else 
      this->hours = 0;
    if(minutes >= 0)
      this->minutes = minutes;
    else
      this->minutes = 0;
  }
  int getMinutes() { return minutes; }
  int getHours() { return hours; }
};
 
int main() {
  Time t1(10,30), t2(12, 50);
  Time t3 = t1 + t2;
}

Προς το παρόν αυτό που θα συμβεί είναι ότι ο παραπάνω κώδικας δεν μεταγλωττίζεται καθώς δεν ορίζεται κάποια συμπεριφορά για τον τελεστή + όταν αυτός εφαρμόζεται σε αντικείμενα τύπου Time. Αυτό μπορεί να αλλάξει εάν ορίσουμε μία συμπεριφορά για αυτό τον τελεστή επαναφορτώνοντας τον ως εξής.

Time.cpp
#include <iostream>
class Time {
  int minutes;
  int hours;
public:
  Time(int hours, int minutes) {
    if(hours >= 0)
      this->hours = hours;
    else 
      this->hours = 0;
    if(minutes >= 0)
      this->minutes = minutes;
    else
      this->minutes = 0;
  }
  Time operator+(const Time &t) {
    Time f(hours, minutes);
    f.minutes += t.minutes;
    if(f.minutes>=60)
      f.minutes -= 60;
    f.hours++;
    f.hours += t.hours;
    if(f.hours > 24)
      f.hours -= 24;
    return f;
  }
  int getMinutes() { return minutes; }
  int getHours() { return hours; }
};
 
int main() {
  Time t1(10,30), t2(12, 50);
  Time t3 = t1 + t2;
  std::cout << "t3: " << t3.getHours() <<"H, " << t3.getMinutes() << "m\n";
}

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

Time t3 = t1.operator+(t2);

Οι συναρτήσεις υπερφόρτωσης τελεστών είναι κανονικές συναρτήσεις που μπορεί να έχουν οποιαδήποτε συμπεριφορά. Για παράδειγμα, δεν υπάρχει κανένας περιορισμός ότι ο τελεστής + θα πρέπει να υλοποιεί την διαδικασία της πρόσθεσης αν και η διατήρηση της συγκεκριμένης συμπεριφοράς συμβάλει στην αναγνωσιμότητα του κώδικα. Γενικά είναι καλή πρακτική η διατήρηση της παραδοσιακής συμπεριφοράς των τελεστών οι οποίοι υπερφορτώνονται.

Η παράμετρος που λαμβάνει μία συνάρτηση υπερφόρτωσης είναι συνήθως ο τελεστέος που βρίσκεται στα δεξιά του τελεστή. Το παραπάνω είναι χαρακτηριστικό για τελεστές που έχουν τελεστέους τόσο στα αριστερά όσο και στα δεξιά τους (binary operators). Όμως δεν είναι όλοι οι τελεστές που εφαρμόζονται με την παραπάνω μορφή.

Επίσης, μία συνάρτηση υπερφόρτωσης μπορεί να είναι μέλος της κλάσης μπορεί όμως να είναι και εξωτερική συνάρτηση (εκτός κλάσης). Σε αυτή την περίπτωση, συνήθως πρόκειται για φιλική συνάρτηση μιας και κατά κανόνα απαιτείται πρόσβαση στα private μέλη της κλάσης.

Ο παρακάτω πίνακας δίνει τη μορφή της συνάρτησης υπερφόρτωσης για τους τελεστές που είναι διαθέσιμοι προς υπεφόρτωση. Αντικαταστήστε τον χαρακτήρα @ με τον εκάστοτε τελεστή.

Έκφραση Τελεστής Υπερφόρτωση ως μέλος της κλάσης Υπερφόρτωση ως μη-μέλος της κλάσης
@a + - * & ! ~ ++ – A::operator@() operator@(A)
a@ ++ – A::operator@(int) operator@(A,int)
a@b + - * / % ^ & | < > == != <= >= << >> && || , A::operator@(B) operator@(A,B)
a@b = += -= *= /= %= ^= &= |= <<= >>= [] A::operator@(B) -
a(b,c…) () A::operator()(B,C…) -
a -> b -> A::operator->() -
(TYPE) a TYPE A::operator TYPE() -

Οι τελεστές που δεν υπερφορτώνονται είναι οι εξής:

:: .* . ?:

Παράδειγμα Υπερφόρτωσης Τελεστών

Ας υποθέσουμε ότι έχουμε την παρακάτω κλάση Vector η οποία λαμβάνει ένα μονοδιάστατο πίνακα από ακεραίους.

Vector.cpp
 

Για την κλάση Vector.

cpp/operator_overloading.1493217812.txt.gz · Last modified: 2017/04/26 13:43 (external edit)