Τελεστές ΤΕΛΕΣΤΕΣ. Γεώργιος Παπαϊωάννου ( )

Σχετικά έγγραφα
Προγραμματισμός Υπολογιστών με C++

Προγραμματισμός Υπολογιστών με C++

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

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

ΚΑΤΑΣΚΕΥΑΣΤΕΣ ΑΝΤΙΓΡΑΦΗΣ

Οντοκεντρικός Προγραμματισμός

ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

ΟΝΤΟΚΕΝΤΡΙΚΟΣ ΠΡΟΓΡ/ΣΜΟΣ C++

Προγραμματισμός Υπολογιστών με C++

ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Προγραμματισμός Υπολογιστών με C++

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

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ Α.Π.Θ. ΕΡΓΑΣΤΗΡΙΟ C++ ΕΞΑΜΗΝΟ Γ Ακαδηµαϊκό Έτος

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

Ονοματεπώνυμο και ΑΜ: Είχα παραδώσει εργασίες τα προηγούμενα ακαδημαϊκά έτη: ΚΑΛΗ ΕΠΙΤΥΧΙΑ!

Ονοματεπώνυμο και ΑΜ: Είχα παραδώσει εργασίες τα εξής ακαδημαϊκά έτη: Διάρκεια: 2,5 ώρες, κλειστά βιβλία και σημειώσεις ΚΑΛΗ ΕΠΙΤΥΧΙΑ!

Προγραμματισμός Υπολογιστών με C++

Προγραμματισμός Υπολογιστών με C++

Προγραμματισμός Υπολογιστών με C++

Κλάσεις και αντικείμενα #include <iostream.h<

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

Προγραμματισμός Ι. Κλάσεις και Αντικείμενα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Στοιχειώδης προγραμματισμός σε C++

ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΚΑΙ ΠΙΝΑΚΕΣ

Προγραμματισμός Υπολογιστών με C++

ΥΠΟΛΟΓΙΣΤΕΣ ΙΙ. Τι είναι ; Συναρτήσεις. Παράδειγμα #1. double convert ( double cm ) { double inch;

ΔΕΙΚΤΕΣ ΚΑΙ ΔΙΕΥΘΥΝΣΕΙΣ

Απάντηση. // We write in a header file named my_header.h #ifndef my_header_h #define my_header_h #define divides(x,y) (((y)%(x)==0)?

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

17TimeThis.h function returns reference pointer to same object { return *this; }

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Αναφορές

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα με πίνακες. Constructors. Υλοποίηση Στοίβας

12. ΑΛΦΑΡΙΘΜΗΤΙΚΑ. υο είδη αλφαριθµητικών Τα αλφαριθµητικά της C πίνακες τύπου char Ta αντικείµενα της κλάσης string

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Ερωτήσεις και απαντήσεις στα θέματα του κανονισμού κατάρτισης

Τελικό τεστ - απαντήσεις

ΣΧΕΔΙΟΤΥΠΑ (TEMPLATES)

ΣΤΟΙΧΕΙΑ ΤΗΣ ΓΛΩΣΣΑΣ C++ Constructors, Destructors, Pointers IO Streams, File Streams

Προγραμματισμός Ι. Εισαγωγή στην C++ Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραμματισμός Υπολογιστών με C++

ΣΥΝΑΡΤΗΣΕΙΣ Παραδείγματα χρήσης συναρτήσεων

Κεφάλαιο 6: Συναρτήσεις IΙΙ Αρθρωτός Προγραμματισμός. (Διάλεξη 14) Παράδειγμα: Αλλαγή τιμής μεταβλητής μόνο τοπικά

Εισαγωγή ΕΙΣΑΓΩΓΗ. Γεώργιος Παπαϊωάννου ( )

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα

ΚΑΛΟΥΠΩΜΑΤΑ & ΜΕΤΑΤΡΟΠΕΣ

Διδάσκων: Παναγιώτης Ανδρέου

Προγραμματισμός Υπολογιστών με C++

υναµική διαχείριση µνήµης στη C++ Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: ΕΠΛ 132 Αρχές Προγραµµατισµού ΙΙ 2 είκτες

3 Αλληλεπίδραση Αντικειμένων

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Μνήμης Αντικείμενα ως ορίσματα

Συναρτήσεις και Πίνακες

Συμβολοσειρές ΣΥΜΒΟΛΟΣΕΙΡΕΣ. Γεώργιος Παπαϊωάννου ( )

Διάλεξη 06: Συνδεδεμένες Λίστες & Εφαρμογές Στοιβών και Ουρών

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Συναρτήσεις I Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language)

Εισαγωγή στον Προγραμματισμό

Προγραμματισμός Υπολογιστών με C++

ΤΕΧΝΟΛΟΓΙΑ ΚΑΙ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

Διανύσματα στις 3 Διαστάσεις

Προγραμματισμός Υπολογιστών με C++

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Αναφορές-Παράμετροι

Εισαγωγή στη JAVA. Εισαγωγή στη Java. Η Java είναι δημιούργημα της SUN MICROSYSTEMS.

Τμήμα Πληροφορικής & Επικοινωνιών Δρ. Θεόδωρος Γ. Λάντζος

Προγραμματισμός Υπολογιστών με C++

Εισαγωγή στον Προγραμματισμό με C++

Προγραμματισμός Υπολογιστών με C++ Φύλλο Διαγωνίσματος Ακαδημαϊκό εξάμηνο: Χειμερινό

ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΤΜΗΜΑ ΜΑΘΗΜΑΤΙΚΩΝ ΙΠΛΩΜΑΤΙΚΗ ΕΡΓΑΣΙΑ

Κεφάλαιο 6: Συναρτήσεις IΙΙ Αρθρωτός Προγραμματισμός. Δείκτες (Διάλεξη 14)

Οντοκεντρικός Προγραμματισμός

Αντικειμενοστρεφής Προγραμματισμός Διάλεξη 2 : ΜΕΤΑΒΛΗΤΕΣ ΤΕΛΕΣΤΕΣ & ΕΚΦΡΑΣΕΙΣ ΕΛΕΓΧΟΣ ΡΟΗΣ

Διάλεξη 5: Δείκτες και Συναρτήσεις

Δομημένος Προγραμματισμός (ΤΛ1006)

Προγραμματισμός Υπολογιστών με C++

Δομή Προγράμματος C++, Χειρισμός Μεταβλητών και Συναρτήσεις Εισόδου - Εξόδου

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Πίνακες Κλάσεις και Αντικείμενα

3 ο Εργαστήριο Μεταβλητές, Τελεστές

POINTERS, AGGREGATION, COMPOSITION

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Υπερφόρτωση Αντικείμενα σαν ορίσματα

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα ως ορίσματα Εισαγωγή στις αναφορές

Εισαγωγή σε αντικειμενοστραφή concepts. Και λίγη C#

ΗΥ-150. Προγραμματισμός

ΗΥ-150. Προγραμματισμός

Προγραμματισμός Υπολογιστών με C++

Δομημένος Προγραμματισμός (ΤΛ1006)

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

Η-Υ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ. Εργαστήριο 2 Εντολές Εισόδου/Εξόδου Τελεστές. Δρ. Γιώργος Λαμπρινίδης 23/10/2015 Η - Υ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ 1

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Δημιουργία Κλάσεων και Αντικειμένων

Προγραμματισμός Η/Υ (ΤΛ2007 )

ΕΠΛ 231 Δομές Δεδομένων και Αλγόριθμοι 4-1

Αντικειμενοστραφής Προγραμματισμός I (5 ο εξ) Εργαστήριο #2 ο : Ανατομία προγραμμάτων εφαρμογών, η

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Μέθοδοι

3ο σετ σημειώσεων - Πίνακες, συμβολοσειρές, συναρτήσεις

ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

I (JAVA) Ονοματεπώνυμο: Α. Μ.: Δώστε τις απαντήσεις σας ΕΔΩ: Απαντήσεις στις σελίδες των ερωτήσεων ΔΕΝ θα ληφθούν υπ όψην.

ΕΠΛ 231 οµές εδοµένων και Αλγόριθµοι Άννα Φιλίππου,

Transcript:

ΤΕΛΕΣΤΕΣ Γεώργιος Παπαϊωάννου (2013-14) gepap@aueb.gr

Περιγραφή: Τι είναι οι τελεστές Χρήση τελεστών Υπερφόρτωση τελεστών Chain-linking Τελεστών Τελευταία ενημέρωση: Ιούνιος 2013 Εισαγωγή - 2

Τελεστής είναι μια βασική πράξη που μπορούμε να εκτελέσουμε πάνω σε ένα ή περισσότερα δεδομένα και να πάρουμε ένα νέο αποτέλεσμα το οποίο είτε επιστρέφεται ως μια νέα τιμή, είτε αποθηκεύεται στο αρχικό όρισμα (π.χ. ο τελεστής ++) Στη C++ οι περισσότεροι από τους γνωστούς τελεστές μπορούν να υπερφορτωθούν 3

Πολύ συχνά θέλουμε να αντικαταστήσουμε μια δύσχρηστη μέθοδο ή συνάρτηση με μια πιο αυθόρμητη και απλή πράξη Παράδειγμα: vec3 v1(1,2), v2(3,4), v3(); v3 = AddVectors(v1,v2); v3 = v1+v2; Θα θέλαμε: Εδώ, πρέπει να επαναπροσδιορίσουμε την έννοια του τελεστή + προκειμένου να υλοποιεί άλλους υπολογισμούς όταν οι τελεστέοι είναι vec3 4

Σχεδόν όλοι! Τόσο σε επίπεδο κλάσης (ως μέθοδοι), όσο και σε μορφή ελεύθερων τελεστών (ως συναρτήσεις) Π.χ: +,-,*,/,++,-=,=,,&,^,~,<<,>>,>,<,==,!=, -> ( ), Τα καλουπώματα (typea)a, typea(a) [ ] Οι τελεστές κλάσεων delete, new, delete[] και new[] (προσοχή, όχι το new που έχουμε δει, αυτό δεν ανήκει σε κλάση) 5

Κάποιες ανακατευθύνσεις: a.b, a.*b Ο τριαδικός τελεστής συνθήκης: a?b:c Ο τελεστής μέλους: a::b Οι τελεστές ελέγχων με βάση τύπο: sizeof(a), typeid(a) Το new και delete (global functions) 6

class vec2 { float x, y; public: vec2(float xx = 0, float yy = 0) { x = xx; y = yy; } void print() const { cout << x << "," << y << endl; } vec2 operator+(const vec2& p) const; }; vec2 vec2::operator+(const vec2& p) const { vec2 temp(x + p.x, y + p.y); return temp; } // Ή κατευθείαν «return vec2(x + p.x, y + p.y);» χωρίς temp. int main() { vec2 p1(1, 2), p2(3, 4); vec2 p3 = p1 + p2; // Χρήση υπερφορτωμένου τελεστή +. vec2 p4 = p1.operator+(p2); // Ισοδύναμη μορφή δε χρησιμοποιείται p1.print(); p2.print(); // Τυπώνουν «1,2», «3,4». p3.print(); p4.print(); // Τυπώνουν «4,6», «4,6». } 7

Μπορούν να υπερφορτωθούν μόνο υπάρχοντες τελεστές της C++ (π.χ., +, ++, >>, <<). Δεν είναι δυνατή η αλλαγή της σύνταξης των τελεστών (π.χ. ο + απαιτεί δύο ορίσματα). Η κλάση τουλάχιστον ενός από τα ορίσματα πρέπει να είναι ορισμένη από το χρήστη (π.χ. δεν επιτρέπεται να αλλάξουμε τη σημασία του + για πρόσθεση ακεραίων). 8

class vec2 { float x, y; public: vec2(float xx = 0, float yy = 0) { x = xx; y = yy; } void print() const { cout << x << "," << y << endl; } void operator++(); }; void vec2::operator++() { ++x; ++y; } int main() { vec2 p1(1, 2), p2; ++p1; // Ισοδύναμα: p1.operator++(); p1.print(); // Τυπώνει «2,3». p2 = ++p1; // Λάθος. Η κλήση ++p1 δεν επιστρέφει τίποτα. } 9

class vec2 { float x, y; public: vec2(float xx = 0, float yy = 0) { x = xx; y = yy; } void print() const { cout << x << "," << y << endl; } vec2 operator++(); }; vec2 vec2::operator++() { return vec2(++x, ++y); } // Αλλάζει τα x και y του αντικειμένου // του οποίου τη μέθοδο καλέσαμε και // επιστρέφει αντίγραφο του αντικειμένου. int main() { vec2 p1(1, 2), p2, p3; p2 = ++p1; // Το ++p1 είναι ένα αντίγραφο του p1. p1.print(); p2.print(); // OK. Τυπώνει «2,3», «2,3». p3 = ++(++p1); // Το αριστερό ++ δεν εφαρμόζεται στο p1, // αλλά στο νέο vec2 που επιστρέφεται. p1.print(); p3.print(); // Πρόβλημα: τυπώνει «3,4», «4,5». } 10

class vec2 { float x, y; public: vec2(float xx = 0, float yy = 0) { x = xx; y = yy; } void print() const { cout << x << "," << y << endl; } vec2& operator++(); }; vec2& vec2::operator++() { ++x; ++y; // Ο δείκτης this == διεύθυνση του αντικειμένου που // καλέσαμε τη μέθοδο. *this είναι αυτό το αντικείμενο. return *this; } void main() { vec2 p1(1, 2), p2, p3; p2 = ++p1; p1.print(); p2.print(); // OK. Τυπώνει «2,3», «2,3». p3 = ++(++p1); // Το ++p1 είναι αναφορά στο p1. p1.print(); p3.print(); } // OK. Τυπώνει «4,5», «4,5». 11

Πώς διαφοροποιούνται οι προθεματικοί (prefix) τελεστές από τους μεταθεματικούς (postfix); Π.χ.: ++a, a++ class vec2 { float x, y; public: vec2(float xx = 0, float yy = 0) { x = xx; y = yy; } void print() const { cout << x << "," << y << endl; } vec2& operator++(); }; vec2& operator++(int); Δε χρησιμοποιείται το όρισμα πουθενά, απλά χρησιμεύει για να καταλάβει ο μεταγλωττιστής ότι πρόκειται για την postfix έκδοση του τελεστή 12

Δεδομένου ότι για παράδειγμα ο τελεστής operator++ (π.χ. v++) είναι μια μέθοδος κατά βάση, δεν απαγορεύεται εν γένει να καλέσουμε: ((v++)++)++ Αυτό όμως συντακτικά απαγορεύεται για τους τελεστές βασικών τύπων Επίσης, η κλήση vec2 v = (v1++)++ δε θα έκανε αυτό που πιθανά να θέλαμε, δηλαδή να αυξήσει το v1 και μετά να το πάρουμε στο v. Ακόμα, τα δεύτερο (δεξιό) ++ που θα εφαρμοζόταν; Δε θα χρησίμευε κάπου. 13

const vec2 vec2::operator++(int) { vec2 temp(x, y); x++; y++; return temp;} int main() { vec2 p1(1, 2), p2; p2 = (p1++)++; // Τώρα πλέον δεν επιτρέπεται, γιατί το // αντικείμενο vec2 (αντίγραφο) που } // επιστρέφει η κλήση p1++ είναι const. p2 = p1++; // Επιτρέπεται. p1.print(); p2.print(); // Τυπώνει «2,3» και «1,2». 14

Όπως μπορώ να ορίσω μεθόδους τελεστές, έτσι μπορώ να ορίσω τελεστές σε global scope Προφανώς, δεν υπάρχει το ίδιο εύρος τελεστών που μπορούν να υπερφορτωθούν (π.χ. δεν ορίζεται ο -> ) 15

Υπάρχουν γενικοί κανόνες για την επιλογή (αλλά προφανώς και εξαιρέσεις ): Αν είναι μοναδιαίος (unary) τελεστής: μέλος της κλάσης Αν είναι δυαδικός (binary) τελεστής που δεν αλλοιώνει καμία από τις δύο κλάσεις ορίσματα: ελεύθερος τελεστής Αν είναι δυαδικός τελεστής που μεταβάλλει ένα από τα ορίσματα, τότε τον κάνουμε μέλος της αντίστοιχης κλάσης Οι τελεστές ->, [ ], ( ) είναι υποχρεωτικά μέλη κλάσης 16

Συχνά χρειάζεται να στοιβάζουμε τελεστές στη σειρά Οι τυπικοί τελεστές που επενεργούν πάνω σε αντικείμενα και επιστρέφουν αντικείμενα του ίδιου τύπου συνδέονται στη σειρά εύκολα Το πρόβλημα προκύπτει όταν στον τελεστή μετέχουν ετερογενή δεδομένα, όπως στην περίπτωση των τελεστών «stream out/in»: <<, >> 17

class vec2 { float x, y; public: vec2(float xx = 0, float yy = 0) { x = xx; y = yy; } friend void operator << (ostream& os, const vec2& p); }; void operator<<(ostream& os, const vec2& p) { os << p.x << ", " << p.y; } // Δεν μπορώ να γράψω απλά «x», «y». int main() { vec2 p1(1, 2); cout << p1; operator<<(cout, p1); cout << p1 << "test"; } // Τυπώνει «1, 2». Το cout ανήκει στην κλάση ostream. // Ισοδύναμη με την προηγούμενη γραμμή. // Δεν δουλεύει, γιατί // το cout << p1 δεν επιστρέφει τίποτα. // Ισοδύναμη μορφή: (cout << p1) << "test"; 18

class vec2 { float x, y; public: vec2(float xx = 0, float yy = 0) { x = xx; y = yy; } friend ostream& operator << (ostream& os, const vec2& p); }; ostream& operator << (ostream& os, const vec2& p) { os << p.x << ", " << p.y; return os; } int main() { vec2 p1(1, 2); cout << p1 << endl << "test" << endl; // OK. // Ισοδύναμη μορφή: (((cout << p1) << endl) << "test") << endl; } 19