c++ operator overloading

Πιστιόλης Κωνσταντίνος pistiolis at ts.sch.gr
Fri Feb 25 10:00:28 EET 2005


Την Thu, 24 Feb 2005 16:31:50 +0200,ο(η) Marios K.  
<marios_hellas_23 at yahoo.gr> έγραψε/wrote:

> On Thu, 2005-02-24 at 14:09 +0000, Kyriakos Oikonomakos wrote:
>> oikka at flanders:~$ vi mvector.h
>
> Dhladh?
> Ti return prepei na exei to int &operator?
>

απλά int, κατά τ' άλλα είναι σα να είχε τύπο int operator[](.....
Ας τα πάρουμε από την αρχή. Εσύ θες κάπου στο πρόγραμμά σου να γράφεις:
	<κάτι> = aaa[5];

Ας πάρουμε την απλή περίπτωση: έστω int operator[](int i);
Μιά συνάρτηση int πρέπει στην τελευταία εντολή να έχει ένα return <κάτι  
int>;
Άν δεν υπάρχει τέτοια εντολή, ο χώρος όπου αποθηκεύεται αυτή η τιμή θα έχει
σκουπίδια. Όταν κάπου στο πρόγραμμα γράφεις <κάτι> = aaa[5]; το <κάτι>
πρέπει να πάρει την τιμή που θα επιστρέψει η συνάρτηση operator[], η οποία
και αν δεν έχει το σχετικό return θα επιστρέφει σκουπίδια, δηλαδή μια τιμή
από INTEGER_MIX ως INTEGER_MAX. Τουλάχιστον το πρόγραμμα δεν κολάει όμως...

Ωραία τα παραπάνω, έχουν όμως ένα προγραμματιστικό μειονέκτημα. όταν κάνεις
return μια τιμή, αυτή αντιγράφεται κάπου προσωρινά ως επιστρεφόμενη τιμή,
και το αντίγραφο αυτό αντιγράφεται στη μεταβλητή <κάτι>. Πολύ αντιγραφή και
μεγάλη σπατάλη πόρων.

Λύση 1: αντί για int operator το κάνεις int *operator
Επιστρέφεις ένα δείκτη σε αυτόν τον αριθμό και αντιγράφεται απ' ευθείας
στο <κάτι>
Μειονέκτημα 1: εμείς θέλουμε να επιστρέφει int. Δε μπορούμε να γράφουμε  
κάτι
στο στύλ <κάτι> = *(ααα[5]);      (και ανάλογα με το μεταγλωττιστή μπορεί  
να μη γίνεται)
Μειονέκτημα 2: θέλει πολύ προσοχή τι επιστρέφεις. Αν επιστρέφεις δείκτη
σε ένα στοιχείο του πίνακα καλώς, αν όμως επιστρέψεις δείκτη σε μια τοπική
μεταβλητή όπου προσωρινά είχες βάλει την τιμή που θέλεις, η μεταβλητή αυτή  
θα
έχει ψοφήσει τη στιγμή που θα γίνει η ανάθεση στο <κάτι> και μάλλον θα έχει
σκουπίδια. Δείκτης με σκουπίδια, δείχνει σε κάποιο segment της μνήμης που
δεν πρέπει και όταν το πρόγραμμα προσπαθήσει να διαβάσει από εκεί για να
βρεί την τιμή που θα βάλει στο <κάτι> βγαίνει το γνωστό μήνυμα που  
συνοδεύει
το κόλημα του προγράμματός σου.


Λύση 2: αντί για int operator το κάνεις int & operator
το οποίο είναι ακριβώς το ίδιο με το προηγούμενο χωρίς το μειονέκτημα 1.
Είναι ένας ΔΕΙΚΤΗΣ που χρησιμοποιείται με τη σύνταξη του απλού int.
Αυτός που καλεί τη συνάρτηση δεν καταλαβαίνει τη διαφορά, και η συνάρτηση
όταν επιστρέφει γράφει απλά return <τιμή> και αυτό μεταφράζεται αυτόματα σε
return &<τιμή>

Σκέψου τι θα γίνει τώρα αν λείπει το return <τιμή> και αυτό που  
επιστρέφεται
είναι σκουπίδια... θα πάρεις ένα δείκτη με σκουπίδα, που όταν θα πάει να
διαβαστεί για να γίνει η ανάθεση στο <κάτι> θα συμβούν όλα τα ωραία  
πράγματα
που αναφέρονται στο "μειονέκτημα 2"


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


Συμβουλή μου, διάβασε πρώτα καλά τι σημαίνει δείκτης, πίνακας, αναφορά,
τοπική, καθολική και στατική μεταβλητή κλπ.
και μετά ασχολήσου με όλα τα υπόλοιπα. Αν πάς να μάθεις C++, κληρονομιές,  
templates
και όλα αυτά που λένε τα βιβλία
"μάθε μόνος σου C++ σε 3 ώρες, χωρίς προηγούμενη εμπειρία... κλπ"
πάντα θα εμφανίζονται προβλήματα με "μαγικό" τρόπο!

Ελπίζω να βοήθησα,
Κώστας




More information about the Linux-greek-users mailing list