User Tools

Site Tools


cpp:operator_overloading

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
cpp:operator_overloading [2019/05/16 06:27]
gthanos
cpp:operator_overloading [2021/05/24 06:28]
Line 1: Line 1:
-====== Υπερφόρτωση τελεστών ====== 
- 
-Η C++ επιτρέπει την //υπεφόρτωση// των περισσότερων από τους διαθέσιμους τελεστές της γλώσσας. Με τον όρο //υπεφόρτωση// εννοούμε τον ορισμό μιας νέας συμπεριφοράς για τον τελεστή όταν αυτός εφαρμόζεται όχι σε βασικούς τύπους δεδομένων, αλλά σε αναφορικούς τύπους δεδομένων. Για παράδειγμα, στην παρακάτω κλάση //Time// τι θα γίνει εάν προσθέσουμε δύο αντικείμενα της κλάσης αυτής; 
- 
-<code cpp 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; 
-} 
-</code> 
- 
-Προς το παρόν αυτό που θα συμβεί είναι ότι ο παραπάνω κώδικας δεν μεταγλωττίζεται καθώς δεν ορίζεται κάποια συμπεριφορά για τον τελεστή ''+'' όταν αυτός εφαρμόζεται σε αντικείμενα τύπου //Time//. Αυτό μπορεί να αλλάξει εάν ορίσουμε μία συμπεριφορά για αυτό τον τελεστή επαναφορτώνοντας τον ως εξής. 
- 
-<code cpp 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"; 
-} 
-</code> 
- 
-<WRAP center round info 80%> 
-Η λειτουργία υπεφόρτωσης ενός τελεστή μπορεί να κληθεί είτε χρησιμοποιώντας τον τελεστή, όπως στο παραπάνω παράδειγμα, είτε καλώντας τη συνάρτηση υπερφόρτωσης. Η κλήση της συνάρτησης υπερφόρτωσης για το παραπάνω παράδειγμα έχει ως εξής: 
-<code cpp> 
-Time t3 = t1.operator+(t2); 
-</code> 
-</WRAP> 
- 
-Οι συναρτήσεις υπερφόρτωσης τελεστών είναι κανονικές συναρτήσεις που μπορεί να έχουν οποιαδήποτε συμπεριφορά. Για παράδειγμα, δεν υπάρχει κανένας περιορισμός ότι ο τελεστής ''+'' θα πρέπει να υλοποιεί την διαδικασία της πρόσθεσης για αντικείμενα τύπου //Time// αν και η διατήρηση της συγκεκριμένης συμπεριφοράς συμβάλει στην αναγνωσιμότητα του κώδικα. Γενικά, είναι καλή πρακτική η διατήρηση της παραδοσιακής συμπεριφοράς των τελεστών που υπερφορτώνονται. 
- 
-<WRAP info 80% center round> 
-Οι τελεστές μπορούν να κατηγοριοποιηθούν σε δύο βασικές κατηγορίες, τους //μοναδιαίους// τελεστές και τους //δυαδικούς// τελεστές. //Μοναδιαίοι// είναι οι τελεστές που λαμβάνουν μόνο ένα μία παράμετρο στα δεξιά ή τα αριστερά τους. Παραδείγματα μοναδιαίων τελεστών είναι τα εξής: **!a, -a, a++**.  
- 
-Οι παράμετροι των τελεστών στο εξής θα καλούνται τελεστέοι. 
- 
-//Δυαδικοί// τελεστές είναι εκείνοι που έχουν δύο τελεστέους, συνήθως ένα στα αριστερά και ένα στα δεξιά του τελεστή. Παραδείγματα δυαδικών τελεστών είναι τα εξής: **a+=b, a+b**. 
- 
-Τόσο οι //μοναδιαίοι// τελεστές όσο και οι //δυαδικοί// τελεστές είναι δυνατόν να μεταβάλλουν ή να μη μεταβάλλουν το αντικείμενο στο οποίο εφαρμόζονται. 
-</WRAP> 
- 
-Οι συναρτήσεις υπερφόρτωσης χωρίζονται σε δύο βασικές κατηγορίες **//α)//** μέλη της κλάσης και **//β)//** φιλικές συναρτήσεις. Για κάθε μία από τις παραπάνω δύο κατηγορίες ισχύουν τα εξής: 
-  * **μέλη της κλάσης:** Για συναρτήσεις υπερφόρτωσης τελεστών που αποτελούν μέλη της κλάσης ισχύουν τα εξής: 
-    * Για μοναδιαίους τελεστές οι συναρτήσεις μέλη θεωρούν ο τελεστέος είναι το αντικείμενο στο οποίο ανήκει η συνάρτηση. Συνήθως οι μοναδιαίοι τελεστές δεν έχουν ορίσματα. Εξαίρεση αποτελούν οι τελεστές αύξησης ή μείωσης κατά ένα (%%++ ή --%%) όταν αυτοί εφαρμόζονται στα δεξιά του αντικειμένου (//postfix increment/decrement operators//), όπου λαμβάνουν ως μοναδικό όρισμα έναν ακέραιο. 
-    * Για δυαδικούς τελεστές οι συναρτήσεις υπερφόρτωσης θεωρούν ότι ο αριστερός τελεστέος είναι το αντικείμενο στο οποίο ανήκει η συνάρτηση και ο δεξιός τελεστέος δίνεται ως η μοναδική παράμετρος. 
-  * **φιλικές συναρτήσεις της κλάσης:** Για φιλικές συναρτήσεις υπερφόρτωσης ισχύουν τα εξής: 
-    * Για μοναδιαίους τελεστές οι φιλικές συναρτήσεις θεωρούν ότι ο τελεστέος είναι το μοναδικό όρισμα της συνάρτησης. Εξαίρεση αποτελούν οι τελεστές αύξησης ή μείωσης κατά ένα (%%++ ή --%%) όταν αυτοί εφαρμόζονται στα δεξιά του αντικειμένου (//postfix increment/decrement operators//), όπου λαμβάνουν δύο ορίσματα με την παρακάτω σειρά α) το αντικείμενο στο οποίο εφαρμόζονται (τελεστέος) και β) έναν ακέραιο. 
-    * Για δυαδικούς τελεστές οι φιλικές συναρτήσεις υπερφόρτωσης λαμβάνουν δύο ορίσματα. Θεωρούν ότι ο αριστερός τελεστέος είναι το πρώτο όρισμα της συνάρτησης υπερφόρτωσης και ο δεξιός τελεστέος το δεύτερο όρισμα.   
- 
-Ο παρακάτω πίνακας δίνει τη μορφή της συνάρτησης υπερφόρτωσης για τους τελεστές που είναι διαθέσιμοι προς υπεφόρτωση. Αντικαταστήστε τον χαρακτήρα ''@'' με τον εκάστοτε τελεστή.  
- 
-^  Έκφραση  ^  Τελεστής  ^  Υπερφόρτωση ως μέλος της κλάσης  ^  Υπερφόρτωση ως φιλική συνάρτηση  ^ 
-|  @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()  |  -  | 
- 
-Οι τελεστές που δεν υπερφορτώνονται είναι οι εξής: 
-|  ::  |  .*  |  .  |  ?:  | 
- 
  
cpp/operator_overloading.txt · Last modified: 2021/05/24 06:28 (external edit)