Με τι ασχολείται ο αντικειμενοστραφής προγραμματισμός

Σχετικά έγγραφα
Τι είναι κλάση Κλάση

Με τι ασχολείται ο αντικειμενοστραφής προγραμματισμός

ΚΛΗΡΟΝΟΜΙΚΟΤΗΤΑ. Σχηματική παράσταση του προγράμματος. logariasmos

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

Διαδικασιακός Προγραμματισμός

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

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

Διαδικασιακός Προγραμματισμός

Διαδικασιακός Προγραμματισμός

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

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

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

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

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

Διαδικαστικός Προγραμματισμός

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

Δομές Δεδομένων (Εργ.) Ακ. Έτος Διδάσκων: Ευάγγελος Σπύρου. Εργαστήριο 3 Επανάληψη Γ μέρος

Προγραμματισμός ΙI (Θ)

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

int array[10]; double arr[5]; char pin[20]; Προγραµµατισµός Ι

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

ΑΣΚΗΣΗ 8 : ΚΛΗΡΟΝΟΜΙΚΟΤΗΤΑ (1) Θεωρητικό μέρος

Δομημένος Προγραμματισμός

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

2ο ΓΕΛ ΑΓ.ΔΗΜΗΤΡΙΟΥ ΑΕΠΠ ΘΕΟΔΟΣΙΟΥ ΔΙΟΝ ΠΡΟΣΟΧΗ ΣΤΑ ΠΑΡΑΚΑΤΩ

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

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

2.1. Εντολές Σχόλια Τύποι Δεδομένων

ΠΑΝΕΠΙΣΤΗΜΙΟ AΙΓΑIΟΥ & ΑΕΙ ΠΕΙΡΑΙΑ Τ.Τ. Τμήματα Ναυτιλίας και Επιχειρηματικών Υπηρεσιών & Μηχ. Αυτοματισμού ΤΕ. Εισαγωγή στη Python

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

Προγραμματισμός Ι. Δομές & Ενώσεις. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

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

Ανάπτυξη και Σχεδίαση Λογισμικού

ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ. Ευάγγελος Γ. Ούτσιος Θεόδωρος Γ. Λάντζος Διάλεξη Νο2-Νο3

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

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

Κεφάλαιο 8.7. Πολυδιάστατοι Πίνακες (Διάλεξη 19)

Διαδικασιακός Προγραμματισμός

Διάλεξη 6: Δείκτες και Πίνακες

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

Λύβας Χρήστος Αρχική επιµέλεια Πιτροπάκης Νικόλαος και Υφαντόπουλος Νικόλαος

Στη C++ υπάρχουν τρεις τύποι βρόχων: (a) while, (b) do while, και (c) for. Ακολουθεί η σύνταξη για κάθε μια:

ΠΛΗΡΟΦΟΡΙΚΗ Ι JAVA Τμήμα θεωρίας με Α.Μ. σε 3, 7, 8 & 9 17/1/08

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

Διαδικασιακός Προγραμματισμός

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

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

Ανάπτυξη και Σχεδίαση Λογισμικού

Διαδικασιακός Προγραμματισμός

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

Κλάσεις και Αντικείµενα

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

Προγραμματισμός ΙI (Θ)

Υπολογιστής - Λογισμικό

Η-Υ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ. Εργαστήριο 1 Εισαγωγή στη C. Σοφία Μπαλτζή s.mpaltzi@di.uoa.gr

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

ΕΞΕΤΑΣΤΕΑ ΥΛΗ (SYLLABUS) ADVANCED αντικειμενοστραφής προγραμματισμός ΕΚΔΟΣΗ 1.0. Σόλωνος 108,Τηλ Φαξ

Εισαγωγή στη γλώσσα προγραμματισμού C++

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

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

Η γλώσσα προγραμματισμού C

Pascal. 15 Νοεμβρίου 2011

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

Διαδικαστικός Προγραμματισμός

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

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

Προγραμματισμός Ι (ΗΥ120)

Πίνακες. 1 Πίνακες. 30 Μαρτίου 2014

3.1 Αριθμητικοί και Λογικοί Τελεστές, Μετατροπές Τύπου (Casting)

Περιεχόμενα. Πρόλογος... 21

2 Ορισμός Κλάσεων. Παράδειγμα: Μηχανή για Εισιτήρια. Δομή μιας Κλάσης. Ο Σκελετός της Κλάσης για τη Μηχανή. Ορισμός Πεδίων 4/3/2008

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

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

Πίνακες: μια σύντομη εισαγωγή. Πίνακες χαρακτήρων: τα "Αλφαριθμητικά"

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Μαθήματα από τα εργαστήρια

a = 10; a = k; int a,b,c; a = b = c = 10;

Σύντομες εισαγωγικές σημειώσεις για την. Matlab

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

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

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

Μεθόδων Επίλυσης Προβλημάτων

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

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

ΑΣΚΗΣΗ 5: ΠΙΝΑΚΕΣ. Σχήµα 1: H έννοια των πινάκων

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

Σύνθεση και Κληρονομικότητα

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

Βασικές Αρχές Προγραμματισμού

Ενδεικτική περιγραφή μαθήματος

Πληροφορική 2. Αλγόριθμοι

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

Ορισμός μεταβλητών δεικτών και αρχικοποίηση

Ανάπτυξη και Σχεδίαση Λογισμικού

ΑΣΚΗΣΗ 6: ΔΕΙΚΤΕΣ. Σκοπός της Άσκησης. 1. Εισαγωγικά στοιχεία για τους Δείκτες

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

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

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

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

Σύνθεση και Κληρονομικότητα

Transcript:

1

2

Η Αρχή Ο αντικειμενοστραφής προγραμματισμός άρχισε να χρησιμοποιείται από τους προγραμματιστές, όταν ουσιαστικά ο διαδικαστικός (δομημένος) προγραμματισμός, δεν μπορούσε να ανταποκριθεί στις νέες απαιτήσεις των προγραμμάτων. Επίσης όσο τα προγράμματα μεγάλωναν και γίνονταν όλο και πιο πολύπλοκα, οι γλώσσες του διαδικαστικού προγραμματισμού εμφάνισαν αδυναμίες στην ανάπτυξή τους. 3

Με τι ασχολείται ο αντικειμενοστραφής προγραμματισμός Ο αντικειμενοστραφής προγραμματισμός, στρέφεται (όπως είναι και ο τίτλος του) στα αντικείμενα τα οποία δημιουργούνται από κατάλληλη επεξεργασία των δεδομένων μελών από τις συναρτήσεις μέλη μιας κλάσης. Συνεπώς τα αντικείμενα είναι οντότητες, οι οποίες ανήκουν σε μία κλάση ή αλλιώς από μια κλάση μπορούμε να δημιουργήσουμε αντικείμενα. Με τον αντικειμενοστραφή προγραμματισμό τα προγράμματα που φτιάχνουμε είναι φιλικά, ευέλικτα, αποδοτικότερα και επαναχρησιμοποιήσιμα. 4

Αντικείμενα (1) Τα αντικείμενα είναι βασικά στοιχεία στον αντικειμενοστραφή προγραμματισμό τα οποία έχουν χαρακτηριστικά αλλά και συμπεριφορές. Με τον όρο χαρακτηριστικό εννοούμε οτιδήποτε καθορίζει την φυσική υπόσταση του αντικειμένου. Με τον όρο συμπεριφορά το πώς συμπεριφέρεται ένα αντικείμενο από μόνο του ή όταν μία ενέργεια επιδράσει επάνω του. Δημιουργία αντικειμένου Αντικειμενοστραφής εφαρμογή Χειρισμός αντικειμένου 5

Αντικείμενα (2) Τα χαρακτηριστικά είναι τα δεδομένα-μέλη της κλάσης τα οποία τα κρύβουμε με ειδικές τεχνικές, για να είναι ασφαλή από τυχόν αλλοίωσή τους. Οι συμπεριφορές είναι οι συναρτήσεις-μέλη της κλάσης οι οποίες χειρίζονται με κατάλληλο τρόπο τα δεδομένα-μέλη της κλάσης. Οι συναρτήσεις-μέλη λέγονται αλλιώς και μέθοδοι μιας κλάσης. Παράδειγμα. Το αντικείμενο Ήρα της κλάσης γάτα έχει χαρακτηριστικά το όνομά της, την ηλικία της, το χρώμα της και συμπεριφορές νιαουρίζει, κοιμάται, τρώει κλπ. 6

Κλάσεις Η κλάση είναι ένα σύνολο από παρόμοια αντικείμενα. Η κλάση είναι το πρότυπο, δηλαδή καθορίζει τα δεδομένα (χαρακτηριστικά) και τις συναρτήσεις (συμπεριφορές) που θα έχουν τα αντικείμενα της κλάσης. Άρα όλα τα αντικείμενα είναι πιστά αντίγραφα της κλάσης στην οποία ανήκουν. Η κλάση κατά τον ορισμό της δεν δημιουργεί αντικείμενα. Τα αντικείμενα δημιουργούνται από άλλους παράγοντες μέσα στο πρόγραμμα (άλλες συναρτήσεις, δομές κλπ). 7

Εγκλεισμός Η διαδικασία της συμπερίληψης όλων των πληροφοριών (δεδομένων και συναρτήσεων) σε ένα μέρος (κλάση), λέγεται εγκλεισμός (encapsulation). Αυτό επιτρέπει τους πελάτες της κλάσης (άλλες κλάσεις ή συναρτήσεις) να χρησιμοποιούν την κλάση χωρίς να τους ενδιαφέρει πως δουλεύει. Για παράδειγμα μπορούμε να οδηγούμε ένα αυτοκίνητο χωρίς να μας ενδιαφέρει πως λειτουργεί η μηχανή. 8

Παράδειγμα Με την βοήθεια της αντικειμενοστραφούς γλώσσας προγραμματισμού C++,με την οποία και θα ασχοληθούμε στο μάθημα ορίζουμε μία κλάση, παράγουμε 2 αντικείμενα της κλάσης και καλούμε μια συνάρτηση της κλάσης από το ένα αντικείμενο. class person { }; //δήλωση της κλάσης person person p1,p2; //δήλωση 2 αντικειμένων της κλάσης person p1.readdata(); //κλήση συνάρτησης από το αντικείμενο p1 9

Κλάση Σχηματική παράσταση Δεδομένο-μέλος Κλήση Συνάρτησης από αντικείμενο class person Name p1 Name Age readdata() Age readdata() p2 Name Αντικείμενο printdata() Age Συνάρτηση-μέλος 10

Κληρονομικότητα (1) Η έννοια της κλάσης στον αντικειμενοστραφή προγραμματισμό είναι άρρηκτα συνδεδεμένη και με την έννοια της κληρονομικότητας. Κληρονομικότητα ονομάζεται η διαδικασία που επιτρέπει μία κλάση να κληρονομεί τις ιδιότητες και την συμπεριφορά μιας άλλης κλάσης. Η κλάση που κληρονομείται λέγεται βασική κλάση (base class) ενώ, Η κλάση που κληρονομεί λέγεται παραγόμενη κλάση (derived class). Για παράδειγμα η κλάση οχήματα χωρίζεται σε επιβατικά, φορτηγά, λεωφορεία κλπ. 11

Κληρονομικότητα (2) Η παραγόμενη κλάση κληρονομεί χαρακτηριστικά και συμπεριφορές από την βασική κλάση αλλά μπορεί να έχει και δικά της. Αν γυρίσουμε στο προηγούμενο παράδειγμα όλα τα οχήματα (βασική κλάση) έχουν κινητήρα και τροχούς (χαρακτηριστικά), ξεκινούν και σταματούν (συμπεριφορά), αλλά τα φορτηγά έχουν καρότσα (χαρακτηριστικό) η οποία ανατρέπεται (συμπεριφορά) και τα λεωφορεία έχουν πολλά καθίσματα (χαρακτηριστικό). Οχήματα Επιβατικά Φορτηγά Λεωφορεία 12

13

Επαναχρησιμοποίηση και Πολυμορφισμός (1) Δύο βασικά χαρακτηριστικά στον αντικειμενοστραφή προγραμματισμό είναι η επαναχρησιμοποίηση και ο πολυμορφισμός. Η επαναχρησιμοποίηση είναι η δυνατότητα χρησιμοποίησης μιας κλάσης όταν οριστεί από άλλα προγράμματα. Είναι κάτι δηλαδή σαν τις βιβλιοθήκες συναρτήσεων της γλώσσας προγραμματισμού όπου μπορούμε να τις χρησιμοποιήσουμε σε πολλά προγράμματα. Επίσης η κληρονομικότητα είναι μια μορφή επαναχρησιμοποίησης αφού μπορούμε να πάρουμε μια κλάση και χωρίς να την τροποποιήσουμε να παράξουμε μία άλλη κλάση προσθέτοντας 14

Επαναχρησιμοποίηση και Πολυμορφισμός (2) επιπλέον χαρακτηριστικά και μεθόδους. Η νέα κλάση κληρονομεί χαρακτηριστικά και μεθόδους από την βασική αλλά χρησιμοποιεί και τα δικά της. Πολυμορφισμός είναι η δυνατότητα που δίνεται: 1. Σε ένα αντικείμενο να αναφέρεται σε διαφορετικές κλάσεις (από αυτή από την οποία δημιουργήθηκε) και να επιδρά διαφορετικά σε άλλα αντικείμενα. 2. Σε μία συνάρτηση να υπάρχει πολλές φορές μέσα σε μία κλάση με το ίδιο όνομα και τον ίδιο σκοπό, αλλά με διαφορετικά αποτελέσματα. 15

Επαναχρησιμοποίηση και Πολυμορφισμός (3) Για παράδειγμα η συνάρτηση πάτησε() λειτουργεί διαφορετικά στο φρένο, διαφορετικά στο γκάζι και διαφορετικά στον συμπλέκτη του αυτοκινήτου. 3. Αλλά και σε έναν τελεστή να λειτουργεί διαφορετικά μέσα σε ένα πρόγραμμα. Συμπέρασμα Τα δύο αυτά χαρακτηριστικά δηλαδή η επαναχρησιμοποίηση και ο πολυμορφισμός είναι πολύ σημαντικά γιατί ουσιαστικά μαζί με την έννοια της κλάσης και του αντικειμένου είναι οι πυλώνες στους οποίους στηρίζεται ο αντικειμενοστραφής προγραμματισμός. 16

17

Συνάρτηση ένα χρήσιμο εργαλείο (1) Είναι απαραίτητο πριν ξεκινήσουμε την γνωριμία με τον αντικειμενοστραφή προγραμματισμό να εξετάσουμε ενδελεχώς ένα πολύ χρήσιμο εργαλείο το οποίο χρησιμοποιούμε κατά κόρο. Αυτό δεν είναι άλλο από τη συνάρτηση. Την συνάρτηση την χρησιμοποιούμε για να εκτελέσουμε έναν συγκεκριμένο αριθμό εντολών που λύνουν ένα μέρος του προβλήματος που καλούμαστε να αντιμετωπίσουμε. Τη συνάρτηση την χρησιμοποιούμε μόνη της μέσα σε ένα πρόγραμμα ή και σαν μέρος των κλάσεων. 18

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

Τι είναι συνάρτηση Συνάρτηση είναι ένα κομμάτι του προγράμματος που εκτελεί μία συγκεκριμένη λειτουργία. Μέσα σε ένα πρόγραμμα της C++ μπορεί να υπάρχουν αυτόνομες συναρτήσεις ή να περιλαμβάνονται μέσα σε κλάσεις. Η συνάρτηση περιέχει εντολές. Καλείται μέσα στην βασική συνάρτηση της C++ (main) ή και από άλλες συναρτήσεις, αλλά και η ίδια καλεί άλλες συναρτήσεις. 20

Σχηματική παράσταση λειτουργίας κλήσεων συναρτήσεων 21

Η συνάρτηση μέσα στο πρόγραμμα Οι συναρτήσεις μέσα σε ένα σημείο του προγράμματος καλούνται αφού πρώτα έχουν δηλωθεί στην αρχή του προγράμματος και έχουν οριστεί συνήθως μετά από την main(). Άρα για να χρησιμοποιήσουμε μια συνάρτηση πρέπει να κάνουμε τα ακόλουθα: Δήλωση: Επισημαίνουμε στον Compiler ότι θα χρησιμοποιήσουμε στο πρόγραμμα τη συνάρτηση. Η δήλωση λέγεται και Πρωτότυπο. Ορισμός: Περιγράφεται η λειτουργία της συνάρτησης με άλλα λόγια γράφουμε τον κώδικα της συνάρτησης. Κλήση: Καλούμε την συνάρτηση ή αλλιώς εκτελούμε τις εντολές της (τον κώδικα). 22

Δήλωση συνάρτησης (1) Η δήλωση μιας συνάρτησης στο πρόγραμμα συντάσσεται ως εξής: int function(int param1, int param2); Όνομα συνάρτησης Τύπος επιστροφής Τύπος παραμέτρων τερματικό εντολής Όνομα παραμέτρων 23

Δήλωση συνάρτησης (2) Το Πρότυπο της συνάρτησης είναι μία εντολή άρα θα τελειώνει με τερματικό εντολής (;). Στη δήλωση (Πρότυπο) και τη κλήση μιας συνάρτησης χρησιμοποιούμε πάντα τερματικό εντολής. Στον ορισμό της ποτέ. 24

Ορισμός συνάρτησης επικεφαλίδα συνάρτησης int function(int param1, int param2) { εντολή1; εντολή2; return(value); } σώμα συνάρτησης Λέξη κλειδί Τιμή επιστροφής 25

Κλήση συνάρτησης Στην κλήση μιας συνάρτησης μέσα σε ένα πρόγραμμα χρησιμοποιούνται α)το όνομά της, β)οι παράμετροι εάν υπάρχουν και γ)το τερματικό εντολής. Δεν χρησιμοποιούμε τον τύπο επιστροφής. void main() { } Εντολή1; Εντολή2; function(param1, param2); Εντολή3; κλήση συνάρτησης 26

Συνάρτηση χωρίς επιστρεφόμενη τιμή Οι συναρτήσεις εάν δεν επιστρέφουν τιμή τότε ο τύπος επιστροφής τιμής δηλώνεται void και δεν υπάρχει μέσα στο σώμα της συνάρτησης η λέξη κλειδί return. Στο παράδειγμα που ακολουθεί, βλέπουμε τον ορισμό της συνάρτησης tempmesure() που δεν επιστρέφει κάποια τιμή. void tempmesure() { } εντολή1; εντολή2; 27

Συνάρτηση με επιστρεφόμενη τιμή Οι συναρτήσεις εάν επιστρέφουν τιμή τότε ο τύπος επιστροφής τιμής δηλώνεται κανονικά (π.χ int, float) και μέσα στο σώμα της συνάρτησης υπάρχει η λέξη κλειδί return η οποία μας επιστρέφει μια τιμή. Στο παράδειγμα που ακολουθεί, βλέπουμε τον ορισμό της συνάρτησης tempmesure() που επιστρέφει την τιμή που προκύπτει από το γινόμενο των παραμέτρων x και y που είναι και τα ορίσματα της συνάρτησης. int tempmesure(int x, int y) { } εντολή1; return x*y; 28

Επιστρεφόμενες τιμές Μια συνάρτηση μπορεί να επιστρέφει: a) μία τιμή δηλαδή: return 10; b) μία παράσταση δηλαδή: return (x>3); (Εδώ επιστρέφεται 0 εάν η παράσταση στην παρένθεση είναι αληθής ή 1 αν είναι ψευδής και όχι την τιμή του x). c) Η ακόμα την τιμή μιας συνάρτησης δηλαδή: return (FunctionOne()); Μπορούμε να έχουμε μέσα σε μία συνάρτηση περισσότερες από μία επιστροφές τιμών δηλαδή: (return 5 else return -1) 29

Τοπικές μεταβλητές Τοπικές μεταβλητές είναι οι μεταβλητές που δηλώνονται μόνο μέσα στην ίδια τη συνάρτηση. Όταν η συνάρτηση επιστρέφει τότε οι μεταβλητές αυτές δεν είναι πλέον διαθέσιμες. Οι μεταβλητές αυτές δηλώνονται όπως και κάθε άλλη μεταβλητή. Επίσης τοπικές μεταβλητές θεωρούμε και τις παραμέτρους (ή αλλιώς τα ορίσματα) της συνάρτησης. Τοπικές θεωρούνται και οι μεταβλητές που δηλώνονται μέσα στην main. 30

Καθολικές μεταβλητές Καθολικές μεταβλητές λέγονται αυτές οι μεταβλητές που δηλώνονται έξω από μία συνάρτηση (έξω και από την main) και έχουν καθολική εμβέλεια. Είναι διαθέσιμες δηλαδή για οποιαδήποτε συνάρτηση μέσα στο πρόγραμμα αλλά και για την main(). Καλό είναι να αποφεύγονται γιατί μπερδεύουν τον κώδικα του προγράμματος. 31

Συναρτήσεις με αναδρομή και επανάληψη Αναδρομικές λέγονται οι συναρτήσεις που καλούν τον εαυτό τους. Χρησιμοποιούνται σε επίλυση πολύπλοκων προβλημάτων. Λόγω του ότι το πρόγραμμα στο οποίο χρησιμοποιούμε αναδρομικές συναρτήσεις γίνεται αργό, καλό θα είναι είτε να χρησιμοποιούμε με μέτρο την αναδρομή ή να χρησιμοποιούμε συναρτήσεις με επανάληψη (loop). Οι συναρτήσεις με επανάληψη καλούνται να λύσουν το πρόβλημα με την χρήση δομών επανάληψης (π.χ. for). 32

Υπερφόρτωση συναρτήσεων Πολλές φορές πρέπει να χρησιμοποιήσουμε πολλές διαφορετικές συναρτήσεις που κάνουν παρόμοιες (συναφείς) δουλειές, αλλά έχουν διαφορετικά ονόματα που πρέπει να θυμόμαστε για να τις χρησιμοποιούμε μέσα στο πρόγραμμα. Για να κάνουμε την ζωή μας πιο εύκολη, χρησιμοποιούμε το ίδιο όνομα για όλες τις όμοιες (συναφείς) συναρτήσεις, με τα ορίσματα τις κάθε μιας ξεχωριστά και στην δήλωση και στην κλήση αλλά και στον ορισμό. Αυτή η διαδικασία στον αντικειμενοστραφή προγραμματισμό ονομάζεται υπερφόρτωση συναρτήσεων. 33

Συναρτήσεις INLINE Όταν ορίσουμε μία συνάρτηση inline τότε ο compiler αντιγράφει τις εντολές της συνάρτησης στην καλούσα συνάρτηση. Με αυτό τον τρόπο το πρόγραμμα γίνεται πιο γρήγορο στις περιπτώσεις που πρέπει να κληθεί μία συνάρτηση πολλές φορές μέσα από μία άλλη. Είναι σαν να έχουμε γράψει τις εντολές της συνάρτησης μέσα στην καλούσα συνάρτηση. Αυτό το κάνουμε όταν η συνάρτηση που καλούμε έχει συνήθως μία εντολή. 34

35

Τι είναι κλάση Κλάση είναι μια συλλογή από μεταβλητές. Αλλιώς είναι ένα σύνολο από: δεδομένα που δηλώνουν τα χαρακτηριστικά της κλάσης (τι είναι) και συναρτήσεις που προδιαγράφουν την συμπεριφορά της κλάσης (τι κάνει). 36

Από τι αποτελείται μία κλάση Η κλάση αποτελείται από δύο συστατικά: Τα δεδομένα είναι μέλη της κλάσης, λέγονται αλλιώς και δεδομένα μέλη ή μεταβλητές μέλη και είναι αυτά που καθορίζουν την κλάση. Παράδειγμα το αυτοκίνητο έχει τροχούς, μηχανή, πόρτες κλπ. Τις συναρτήσεις ή αλλιώς συναρτήσεις μέλη είναι αυτές που καθορίζουν την συμπεριφορά της κλάσης. Χειρίζονται τις μεταβλητές μέλη και ονομάζονται αλλιώς και μέθοδοι. Παράδειγμα οι μέθοδοι της κλάσης αυτοκίνητο είναι η Εκκίνηση(), το Φρενάρισμα(), το Σταμάτημα(). 37

Εγκλεισμός Η διαδικασία της συμπερίληψης όλων των πληροφοριών (δεδομένων και συναρτήσεων) σε ένα μέρος (κλάση), λέγεται εγκλεισμός (encapsulation). Αυτό επιτρέπει τους πελάτες της κλάσης (άλλες κλάσεις ή συναρτήσεις) να χρησιμοποιούν την κλάση χωρίς να τους ενδιαφέρει πως δουλεύει. Για παράδειγμα μπορούμε να οδηγούμε ένα αυτοκίνητο χωρίς να μας ενδιαφέρει πως λειτουργεί η μηχανή. 38

Δήλωση μιας κλάσης (1) Η δήλωση μιας κλάσης γίνεται έξω από την main. Αρχίζει με τη δεσμευμένη λέξη class και το όνομα της κλάσης. Ακολουθεί αριστερό άγκιστρο. Κατόπιν ακολουθούν οι λέξεις public ή private (θα αναφερθούμε σε αυτές πιο κάτω) και το κυρίως σώμα της κλάσης που περιέχει τα δεδομένα μέλη και τις συναρτήσεις μέλη. Στο τέλος η κλάση κλείνει με το δεξί άγκιστρο και το ελληνικό ερωτηματικό. 39

Δήλωση μιας κλάσης (2) Πιο κάτω βλέπουμε την δήλωση της κλάσης Car. class Car { public }; int numofdoors; int numofwheels; Start(); Run(); Break(); Τέλος κλάσης Όνομα κλάσης Συναρτήσεις μέλη Δεδομένα μέλη 40

Αντικείμενα μιας κλάσης (1) Ορίζουμε ένα αντικείμενο της κλάσης Car που δηλώσαμε προηγουμένως όπως πιο κάτω: Car Van; Ο ορισμός αντικειμένου γίνεται έξω από την κλάση. Το Van είναι ένα αντικείμενο της κλάσης Car. Για να δηλώσουμε ότι το αντικείμενο Van έχει 3 πόρτες (δεδομένο), ξεκινά (συνάρτηση) και στρίβει (συνάρτηση) δηλαδή για να έχουμε πρόσβαση στα μέλη πλέον του αντικειμένου γράφουμε: Van.numOfDoors=3; 41

Αντικείμενα μιας κλάσης (2) Van.Start(); Van.Turn(); Βλέπουμε ότι για να έχει πρόσβαση το αντικείμενο που φτιάξαμε στα δεδομένα και τις συναρτήσεις της κλάσης χρησιμοποιούμε τον τελεστή τελεία (.). Το δεδομένο μέλος numofdoors της κλάσης παίρνει την τιμή 3. Οι συναρτήσεις Start() και Turn() είναι δηλωμένες μέσα στην κλάση και καλούνται από το αντικείμενο για να ξεκινήσει και στην συνέχεια να στρίψει. 42

Πρόσβαση στα δεδομένα της κλάσης Στη δήλωση μιας κλάσης χρησιμοποιούμε τις δεσμευμένες λέξεις public (δημόσιο) ή private (ιδιωτικό) για να δηλώσουμε αν τα μέλη της κλάσης είναι δημόσια ή ιδιωτικά προσπελάσιμα. Εξ ορισμού είναι όλα ιδιωτικά, μπορούν να προσπελαστούν δηλαδή από μεθόδους της ίδια της κλάσης. Τα δημόσια μπορούν να προσπελαστούν και έξω από την κλάση. Συνήθως τα δεδομένα είναι ιδιωτικά και οι συναρτήσεις δημόσιες. 43

Δήλωση της κλάσης με προσπελασιμότητα class Car { pivate Char Model[50]; int numofdoors; int numofwheels; public void Start(); void Break(); }; Δεδομένα μέλη ιδιωτικά ορατά Συναρτήσεις μέλη δημόσια ορατές 44

Ορισμός της μεθόδου Ο ορισμός μεθόδου (συνάρτησης μέλους) γίνεται έξω από την κλάση ως ακολούθως: τύπος Κλάση::συνάρτηση(παράμετροι) { } Εντολή; Για να δηλώσουμε στον compiler σε ποια κλάση ανήκει η συνάρτηση την οποία ορίζουμε χρησιμοποιούμε τον τελεστή διακρίβωσης εμβέλειας (: :). Ο ορισμός μπορεί να γίνει και μέσα στην κλάση χωρίς τον τελεστή (: :). 45

Constructor Όπως αρχικοποιούμε τις μεταβλητές μας σε μία τιμή, έτσι αρχικοποιούμε και τα δεδομένα μέλη μιας κλάσης. Αυτό επιτυγχάνεται με την χρήση μιας συνάρτησης μέλος της κλάσης που ονομάζεται constructor. Ο constructor έχει το ίδιο όνομα με την κλάση, δηλώνεται μέσα ή και έξω από την κλάση, μπορεί να έχει παραμέτρους που μπορεί να είναι προκαθορισμένες, αλλά δεν επιστρέφει τιμή, ούτε void. 46

Destructor Κατά την κατασκευή του constructor δεσμεύεται χώρος στην μνήμη για να δεχθεί τον constructor. Για να καθαρίσουμε την μνήμη από το αντικείμενο όταν αυτό τελειώσει την δουλειά του φτιάχνουμε μαζί του και το destructor. Ο destructor καθαρίζει το αντικείμενο και ελευθερώνει την μνήμη που έχει δεσμευθεί για αυτό. Δεν παίρνει ορίσματα δεν έχει εντολές και δεν επιστρέφει τιμή. Έχει και αυτός το ίδιο όνομα με την κλάση έχοντας μπροστά από το όνομά του μια περισπωμένη ( ~ ). 47

Παράδειγμα δήλωσης και ορισμού (1) Πιο κάτω ακολουθεί ένα παράδειγμα δήλωσης Constructor και Destructor και ορισμού τους έξω από την κλάση. class Dog //dhlosh klashs { private int DogAge; //dedomeno melos public: Dog(); //dhlosh constructor ~Dog(); //dhlosh destructor }; //telos klashs 48

Παράδειγμα δήλωσης και ορισμού (2) Dog::Dog() { DogAge=0; } Dog::~Dog() { } //orismos constructor //arxikopoihsh toy dedomenoy //orismos tou destructor // den exei entoles 49

Παράδειγμα δήλωσης και ορισμού (3) Δήλωση και ορισμός τους μέσα στην κλάση. class Dog //dhlosh klashs { public: Dog() //orismos tou constructor { DogAge =0; } ~Dog() //orismos tou destructor {} }; //telos klashs 50

51

Constructor με υπερφόρτωση Μπορούμε να φτιάξουμε μία συνάρτηση εγκατάστασης (constructor) που με αυτήν να δίνουμε αρχικές τιμές σε αντικείμενα την στιγμή που αυτά δημιουργούνται. Αυτό επιτυγχάνεται ορίζοντας παραμέτρους στις συναρτήσεις αυτές. Μπορούμε επίσης στην ίδια κλάση να χρησιμοποιούμε constructor με όρισμα και χωρίς. Αυτό ονομάζεται υπερφόρτωση του constructor. Το ποιος constructor εκτελείται κατά την δημιουργία του αντικειμένου εξαρτάται από τα ορίσματα του constructor. 52

Παράδειγμα υπερφόρτωσης constructors Dog() //constructor xoris orisma { DogAge=0; } Dog(int initialage) //constructor me orisma { DogAge=initialAge; } ~Dog() //destructor { } 53

Χρήση αντικειμένου μέσα σε συναρτήσεις Μπορούμε να χρησιμοποιήσουμε αντικείμενα μέσα σε συναρτήσεις: σαν παραμέτρους συνάρτησης (πρόσβαση των παραμέτρων της συνάρτησης που δέχεται τα αντικείμενα στα δεδομένα των αντικειμένων). αλλά και να φτιάξουμε συναρτήσεις που να επιστρέφουν αντικείμενα (ο τύπος επιστροφής της συνάρτησης είναι η ίδια η κλάση). Μπορούμε να δηλώσουμε αντικείμενα μιας κλάσης α μέσα σε μια άλλη κλάση β για να μπορεί η κλάση β να έχει πρόσβαση στα δεδομένα της κλάσης α. 54

Παράδειγμα χρήσης αντικειμένου σαν όρισμα συνάρτησης (1) void athrypoloipo(logariasmos a, logariasmos b) { ypoloipo=a.ypoloipo+b.ypoloipo; } Όνομα κλάσης log3.athrypoloipo(log1,log2); //klhsh synarthshs Στο παραπάνω παράδειγμα φτιάχνουμε μία συνάρτηση η οποία προσθέτει τα υπόλοιπα των δύο πρώτων αντικειμένων (log1 και log2). 55

Παράδειγμα χρήσης αντικειμένου σαν όρισμα συνάρτησης (2) Το αντικείμενο log3 κάνει κλήση αυτής της συνάρτησης από όπου μεταβιβάζονται τα αντικείμενα log1 και log2 στις παραμέτρους της συνάρτησης a και b αντίστοιχα. Μέσα στο σώμα της συνάρτησης βλέπουμε την πρόσβαση αυτής στο δεδομένο του κάθε αντικειμένου (a.ypoloipo b.ypoloipo). Τα δεδομένα αυτά αν και είναι ιδιωτικά μπορούν να προσπελαστούν από την συνάρτηση, γιατί είναι μέλος της κλάσης. 56

Παράδειγμα επιστροφής αντικειμένου από συνάρτηση (1) logariasmos athrypoloipo(logariasmos log) { logariasmos apotelesma; apotelesma.ypoloipo=ypoloipo+log.ypoloipo; return apotelesma; } log3=log1.athrypoloipo(log2); //klhsh synarthshs Σε αυτό το παράδειγμα μεταβιβάζουμε στην συνάρτηση athrypoloipo μόνο το ένα αντικείμενο στην παράμετρο log (το log2 στο log). 57

Παράδειγμα επιστροφής αντικειμένου από συνάρτηση (2) Η τιμή του δεδομένου ypoloipo προστίθεται στην τιμή του δεδομένου του αντικειμένου που καλεί την συνάρτηση δηλ του log1. Μέσα στην συνάρτηση ορίζουμε ένα αντικείμενο apotelesma στο οποίο θα εκχωρηθεί η τιμή της πρόσθεσης. Κατόπιν με την εντολή return το αντικείμενο apotelesma επιστρέφεται μέσα στην καλούσα συνάρτηση main και αποδίδεται στο αντικείμενο log3. 58

Δηλώσεις κλάσεων σε αρχεία επικεφαλίδας (1) Τις κλάσεις έχουμε μάθει να τις δηλώνουμε μέσα στο κυρίως πρόγραμμα. Ένας άλλος τρόπος που υιοθετείται και είναι ο πιο σωστός είναι, τις δηλώσεις να τις κάνουμε σε ένα άλλο αρχείο το λεγόμενο αρχείο επικεφαλίδας και να το επισυνάπτουμε μέσα στο αρχείο του κυρίως προγράμματος μας. Τα αρχεία αυτά μπορεί να έχουν οποιοδήποτε όνομα αλλά επέκταση.hpp. (π.χ. το πρόγραμμα μας είναι το test.cpp το αρχείο κεφαλίδας είναι το car.hpp). Η επόμενη δουλειά είναι να εισάγουμε το αρχείο κεφαλίδας car.hpp μέσα στο αρχείο κώδικα test.cpp. 59

Δηλώσεις κλάσεων σε αρχεία επικεφαλίδας (2) Έτσι οι πελάτες της κλάσης οι οποίοι δεν ενδιαφέρονται για τις λεπτομέρειες της κλάσης, μπορούν να την χρησιμοποιούν αφού όλες οι δηλώσεις υπάρχουν μέσα στο αρχείο επικεφαλίδας το οποίο διαβάζει ο compiler. Παράδειγμα: Το αρχείο που έχει την δήλωση της κλάσης dog είναι το dog.hpp. class dog { Private: DogAge; 60

Δηλώσεις κλάσεων σε αρχεία επικεφαλίδας (3) Public: int GetAge() { return itsage; } }; 61

Δηλώσεις κλάσεων σε αρχεία επικεφαλίδας (4) Το αρχείο του κυρίως προγράμματος είναι το dog.cpp το οποίο συμπεριλαμβάνει το αρχείο κεφαλίδας dog.hpp ως εξής: #include <iostream.h> #include dog.hpp void main() {.. } 62

Σταθερές συναρτήσεις μέλη (1) Μπορούμε να ορίσουμε μια συνάρτηση σαν σταθερή (const) όταν θέλουμε να διασφαλίσουμε ότι αυτή η συνάρτηση δεν θα αλλάξει την τιμή οποιουδήποτε δεδομένου μέλους της κλάσης μας. Ο ορισμός γίνεται ως εξής: void function() const; Αν δηλώσουμε ως σταθερά μία συνάρτηση που πρέπει να επιφέρει αλλαγές σε δεδομένα μέλη της κλάσης μας, τότε θα πάρουμε μήνυμα λάθους από τον compiler. 63

Σταθερές συναρτήσεις μέλη (2) Για παράδειγμα: Μέσα στην κλάση Dog έχουμε την συνάρτηση setage() που αλλάζει το μέλος DogAge και την GetAge() η οποία απλώς μας επιστρέφει την τιμή του μέλους και την οποία θα ορίσουμε ως σταθερά. Δηλαδή ο ορισμός των συναρτήσεων θα είναι: void SetAge(int age); Int GetAge() const; 64

Μέθοδοι INLINE Όπως κάνουμε τις συναρτήσεις inline έτσι μπορούμε να κάνουμε και τις μεθόδους μιας κλάσης inline. Δηλαδή η μέθοδος GetAge() που ορίζεται έξω από την κλάση Dog : Inline int Dog::GetAge() { return DogAge; } Θα γίνει πιο σωστά μέσα στην κλάση Dog: Int GetAge() const {return DogAge;} 65

Στατικά δεδομένα μέλη Όταν τα δεδομένα μέλη ορίζονται ως ιδιωτικά, τότε το κάθε νέο αντικείμενο που δημιουργείται, παίρνει ένα ξεχωριστό δικό του αντίγραφο για τα δεδομένα αυτά. Εάν ορίσουμε κάποιο δεδομένο σαν στατικό (static), τότε όλη η κλάση έχει μόνο ένα αντίγραφο του δεδομένου, όσα αντικείμενα και αν δημιουργηθούν. Ένα στατικό δεδομένο αρχικοποιείται στην κλάση και αλλάζει τιμή με κάθε αντικείμενο Τα στατικά δεδομένα είναι χρήσιμα, όταν πρέπει όλα τα αντικείμενα μιας κλάσης, να μοιραστούν μια πληροφορία. 66

67

Τι είναι πίνακας (1) Πίνακας (array) είναι ένα σύνολο από θέσεις μνήμης (μεταβλητές), όπου η κάθε μία περιέχει τον ίδιο τύπο δεδομένων (π.χ int, float κλπ). Κάθε θέση ονομάζεται στοιχείο του πίνακα. Δηλώνουμε έναν πίνακα στο πρόγραμμα γράφοντας τον τύπο, το όνομα του πίνακα και τέλος έναν δείκτη (subscript) μέσα σε τετράγωνες αγκύλες που είναι ο αριθμός των στοιχείων του πίνακα. Δηλαδή: int ArrayName[25]; 68

Μέγεθος στη μνήμη Ο μεταγλωττιστής για αυτόν τον πίνακα δεσμεύει 100 bytes (δηλ. int 4 bytes x 25 στοιχεία). Τα στοιχεία του πίνακα μετριούνται από το 0, δηλαδή το πρώτο στοιχείο του πίνακα είναι ArrayName[0], το δεύτερο ArrayName[1], το τρίτο ArrayName[2] κλπ. Αρα εάν έχουμε έναν πίνακα με n στοιχεία, η αρίθμηση τους είναι: ΌνομαΠίνακα[0],ΌνομαΠίνακα[1], ΌνομαΠίνακα[n-1] Άρα ο πίνακας του παραδείγματος έχει στοιχεία που μετριούνται από το ArrayName[0] έως το ArrayName[24]. 69

Εγγραφή σε συγκεκριμένη θέση μνήμης Ο μεταγλωττιστής υπολογίζει που θα αποθηκεύσει την τιμή σε ένα στοιχείο του πίνακα ανάλογα με το μέγεθος του (τύπος) και τον δείκτη. Π.χ θέλουμε να γράψει μία τιμή στο στοιχείο ArrayName[5] (έκτο στοιχείο), ο μεταγλωττιστής πολλαπλασιάζει την μετατόπιση επί το μέγεθος του κάθε στοιχείου 5Χ4 bytes=20 bytes. Μετακινείται από την αρχή 20 bytes και γράφει την τιμή του στοιχείου. Προσοχή!! εάν του δώσουμε να γράψει στο ArrayName[50], αγνοεί ότι δεν υπάρχει αυτό το στοιχείο στον πίνακα, υπολογίζει την απόσταση (200 bytes) και πάει και γράφει εκεί που μπορεί να υπάρχουν άλλα δεδομένα. 70

Αρχικοποίηση μονοδιάστατου πίνακα Αρχικοποιούμε έναν μονοδιάστατο πίνακα γράφοντας: int intarray[5]={1,11,21,31,41}; Αυτό σημαίνει ότι το στοιχείο: intarray[0] θα πάρει την τιμη 1, το intarray[1] την τιμή 11, το intarray[2] την τιμή 21, το intarray[3] την τιμή 31 και το intarray[4] την τιμή 41. 71

Παρατηρήσεις Εάν στη δήλωση παραλείψουμε τον δείκτη του πίνακα αλλά βάλουμε τις τιμές, τότε ο compiler θα φτιάξει έναν πίνακα που να χωρέσει τις τιμές αυτές. Δεν πρέπει να αρχικοποιούμε έναν πίνακα με τιμές περισσότερες από το μέγεθός του. Εάν αρχικοποιήσουμε έναν πίνακα με λιγότερες τιμές τότε θα αρχικοποιηθούν τα πρώτα στοιχεία με τις δοθείσες τιμές και τα υπόλοιπα με τιμές 0. Προσοχή στον δείκτη μέσα στις αγκύλες. Στη δήλωση int intarray[5]; ο δείκτης 5 καθορίζει το μέγεθος του πίνακα, ενώ στην πρόταση intarray[4]=41; ο δείκτης 4 δηλώνει ότι το 5ο στοιχείο του πίνακα που αναφερόμαστε, θα πάρει την τιμή 41. 72

Υπολογισμός μεγέθους πίνακα Μπορούμε να βρούμε το μέγεθος σε bytes ενός πίνακα χρησιμοποιώντας τον τελεστή sizeof(). Η δήλωση: sizeof(ονομα_πίνακα) μας δείχνει το μέγεθος (σε bytes) του πίνακα. Η δήλωση: sizeof(ονομα_πίνακα[δείκτης]) μας δείχνει το μέγεθος του συγκεκριμένου στοιχείου του πίνακα. Και η διαίρεση: sizeof(ονομα_πίνακα) / sizeof(ονομα_πίνακα[δείκτης]) μας δείχνει το αριθμό των στοιχείων του πίνακα. 73

Δισδιάστατοι πίνακες (1) Δισδιάστατοι είναι οι πίνακες των οποίων τα στοιχεία είναι επίσης πίνακες. Η πρόταση : int array[3][10]; δηλώνει το array σαν πίνακα ακεραίων 3 στοιχείων, που κάθε στοιχείο του είναι ένας πίνακας ακεραίων 10 στοιχείων. Στην C και την C++ δεν υπάρχει περιορισμός στον αριθμό διαστάσεων ενός πίνακα. 74

Δισδιάστατοι πίνακες (2) Για να αναφερθούμε σε ένα στοιχείο ενός δισδιάστατου πίνακα θα πρέπει να καθοριστούν σωστά οι δείκτες. Δηλ. η έκφραση: array[2] αναφέρεται στην τρίτη γραμμή του πίνακα array Ενώ η έκφραση: array[2][4] αναφέρεται στο πέμπτο στοιχείο της τρίτης γραμμής του πίνακα array array[γραμμή][στοιχείο] 75

Αρχικοποίηση δισδιάστατου πίνακα (1) Για να αρχικοποιηθεί ένας δισδιάστατος πίνακας, θα πρέπει κάθε γραμμή με τιμές, να περικλείεται από άγκιστρα. Αν δεν υπάρχουν σε κάποια στοιχεία τιμές τότε τα στοιχεία αυτά παίρνουν την τιμή 0. Όταν εκτελεστεί η πρόταση: int array[3][3]={ {1,2,3},{4,5,6},{7,8,9} }; ο πίνακας που δημιουργείται είναι ο: 1 2 3 4 5 6 7 8 9 76

Αρχικοποίηση δισδιάστατου πίνακα (2) Προσέχουμε πάντα που βάζουμε τα άγκιστρα. Η δήλωση: 1 η γραμμή 2 η γραμμή 3 η γραμμή int Arr[4][3]={{3,2,1},{6,4},{7,8,9}}; θα δημιουργήσει τον πίνακα: 3 2 1 6 4 0 7 8 9 0 0 0 77

` ` Αρχικοποίηση δισδιάστατου πίνακα (3) Στον ίδιο πίνακα η δήλωση χωρίς τα εσωτερικά άγκιστρα: 1 η γραμμή 2 η γραμμή 3 η γραμμή int Arr[4][3]={3,2,1,6,4,7,8,9}; θα δημιουργήσει τον πίνακα: 3 2 1 6 4 7 8 9 0 0 0 0 78

Πολυδιάστατοι πίνακες Ένας πολυδιάστατος πίνακας δηλώνεται όπως παρακάτω: Τύπος όνομα_πίνακα [διάσταση 1][διάσταση 2]. [διάσταση n] Δήλωση και αρχικοποίηση ενός ακέραιου πίνακα 2Χ2Χ2 γίνεται: int Array[2][2][2]= {{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}}; k j i ΔΙΑΣΤΑΣΕΙΣ ΠΟΛΥΔΙΑΣΤΑΤΟΥ ΠΙΝΑΚΑ Η προσπέλαση του πίνακα γίνεται με 3 βρόχους for και τρεις δείκτες δηλ. Array[i][j][k] 79

Αναγνωριστικό define (1) Στην C++ χρησιμοποιούμε το αναγνωριστικό define για να αντικαταστήσουμε μία έκφραση, μία δήλωση, ή έναν αριθμό που δηλώνει στοιχεία ενός πίνακα με ένα γράμμα ή μία λέξη, έτσι ώστε να μην χρειάζεται να θυμόμαστε τον αριθμό των στοιχείων. Η σύνταξη είναι η εξής: # define <αναγνωριστικό> <αντικατάσταση> Π.χ τον αριθμό των στοιχείων ενός μονοδιάστατου πίνακα μπορούμε σε όλο το πρόγραμμα να τον αντικαταστήσουμε με ένα γράμμα (π.χ Ν) ή μια λέξη (π.χ. CITY). # define N 10 ή # define CITY 10 80

Αναγνωριστικό define (2) Αντικαθιστούμε τον αριθμό 10 με το γράμμα Ν ή την λέξη CITY. Δηλ. για να διαβάσουμε αυτόν τον πίνακα θα γράψουμε τις προτάσεις: for (i=0;i<n;i++) cin>>arr[i]; ή for (i=0;i<city;i++) cin>>arr[i]; Αυτός ο βρόχος θα εισάγει τιμές και στα 10 (Ν ή CITY) στοιχεία του πίνακα. Σε δισδιάστατο πίνακα χρησιμοποιούμε δύο αναγνωριστικά. Π.χ Ν,Μ και διπλό (εμφωλευμένο βρόχο for). 81

Πίνακες μέσα σε κλάσεις (1) Οι πίνακες μπορούν να δηλωθούν σαν δεδομένα-μέλη μιας κλάσης και να χρησιμοποιηθούν μέσα στις μεθόδους της κλάσης. Π.χ private: int temp; float arr[n]; Δεδομένο μέλος Πίνακας σαν δεδομένο μέλος 82

Πίνακες μέσα σε κλάσεις (2) Χρήση πίνακα μέσα σε μέθοδο με επανάληψη: public: //δημόσια ορατά tempmesure() //μέθοδος { int i; //τοπική μεταβλητή for(i=0; i<n; i++) temparr[i]=0; //μηδενισμός στοιχείων } 83

Πίνακες με αντικείμενα Μπορούμε να έχουμε σε ένα πρόγραμμα και πίνακες που να περιέχουν αντικείμενα. Εδώ έχουμε έναν πίνακα αντικειμένων tem της κλάσης Temperature. Σε κάποιο σημείο του προγράμματος κάποιο αντικείμενο του πίνακα (ή όλα τα αντικείμενα μέσα σε βρόχο for) καλεί την μέθοδο readtemp(). main() { } Temperature tem[n]; tem[i].readtemp(); 84

85

Τι είναι κληρονομικότητα Κληρονομικότητα ονομάζεται η διαδικασία που επιτρέπει μία κλάση να κληρονομεί τις ιδιότητες (δεδομένα) και τις συμπεριφορές (συναρτήσεις) μιας άλλης κλάσης. Η κλάση που κληρονομείται λέγεται βασική κλάση (basic class) ενώ, Η κλάση που κληρονομεί λέγεται παραγόμενη κλάση (derived class). 86

Πλεονέκτημα της κληρονομικότητας Βασικό πλεονέκτημα της κληρονομικότητας είναι ότι χρησιμοποιείται ο ήδη γραμμένος κώδικάς μιας κλάσης, που με κάποιες προσθήκες προσαρμόζεται σε μία κλάση που κληρονομεί (παραγόμενη κλάση), αυτό λέγεται επαναχρησιμοποίηση κώδικα. Έτσι δεν χρειάζεται να ξαναγράψουμε τον κώδικα από την αρχή για μια νέα κλάση. Αυτό έχει σαν αποτέλεσμα να εξοικονομούμε χρόνο και χρήμα αλλά και να καθιστούμε το πρόγραμμα πιο αξιόπιστο και εύκολα αναγνώσιμο. 87

88

Σύνταξη βασικής και παραγόμενης κλάσης Ο ορισμός της βασικής αλλά και της παραγόμενης κλάσης μέσα στον κώδικα της C++ γίνεται ως εξής: class παράγωγη_κλάση : public βασική_κλάση Η παράγωγη κλάση κληρονομεί και τα χαρακτηριστικά αλλά και τις μεθόδους της βασικής κλάσης. 89

Προστατευόμενα δεδομένα Τα δεδομένα στην βασική κλάση πρέπει να δηλωθούν ως protected για να μπορούν να έχουν πρόσβαση σε αυτά (ή αλλιώς να τα προσπελάσουν) οι συναρτήσεις-μέλη της ίδιας της κλάσης αλλά και οι συναρτήσεις-μέλη παραγόμενων κλάσεων. Σε αντίθεση με την δήλωση private όπου μπορεί να έχει πρόσβαση στα δεδομένα, μόνο η κλάση στην οποία ανήκουν. Σημ. Δεν μπορούν να έχουν πρόσβαση στα δεδομένα συναρτήσεις που βρίσκονται έξω από αυτές τις κλάσεις δηλ. στην main(). 90

Δήλωση προσβασιμότητας σε κλάση class basic { protected: int mesure; public: Basic() { mesure=0; } Βασική κλάση Προστατευμένο δεδομένο - μέλος 91

Προσβασιμότητα δεδομένων στην κληρονομικότητα Λέξη κλειδί Έχει πρόσβαση η κλάση που ανήκει Έχει πρόσβαση και η παραγόμενη κλάση Έχουν πρόσβαση συναρτήσεις έξω από την κλάση που ανήκει private ----- ----- protected ----- public 92

Συνδυασμοί παραγωγής μιας κλάσης (1) Πρέπει να αναφέρουμε ότι οι κλάσεις μπορούν να παραχθούν είτε δημόσια δηλ: ή ιδιωτικά δηλ: class ProdA:public Basic class ProdΒ:private Basic Εδώ η κλάση ProdA παράγεται δημόσια από την Basic, ενώ η ProdB παράγεται ιδιωτικά από την Basic. 93

Συνδυασμοί παραγωγής μιας κλάσης (2) Πρακτικά οι παράγωγες κλάσεις είτε ιδιωτικά είτε δημόσια παραγόμενες μπορούν να προσπελάσουν δεδομένα της βασικής κλάσης που είναι προστατευμένα (protected) ή δημόσια (public) και ποτέ τα ιδιωτικά (private). : public Private data Protected data Public data : private 94

Συνδυασμοί παραγωγής μιας κλάσης (3) Επίσης αντικείμενα της παράγωγης κλάσης μπορούν να προσπελάσουν δημόσια δεδομένα της βασικής κλάσης μόνο εάν η κλάση παράγεται δημόσια (δηλ η κλάση ProdA). Εάν η παράγωγη κλάση παράγεται ιδιωτικά (ProdΒ) δεν μπορούν να προσπελάσουν ούτε τα δημόσια δεδομένα. : public basic Private data1 Protected data2 Public data3 objecta objecta.data3; objectb : private basic 95

Συνδυασμοί παραγωγής μιας κλάσης (4) Όταν δεν δηλώνουμε κατά την παραγωγή μιας κλάσης την λέξη κλειδί της προσπέλασης (public ή private), τότε θεωρείται από το πρόγραμμα ότι αυτή η κλάση παράγεται ιδιωτικά (private). class ProdA : Basic 96

Αντίστροφα δουλεύει; ΠΡΟΣΟΧΗ!!! Η κληρονομικότητα δεν λειτουργεί αντίστροφα. Δηλαδή εάν φτιάχναμε στην main() ένα αντικείμενο της βασικής κλάσης, αυτό θα είχε πρόσβαση μόνο!! στις μεθόδους της βασικής κλάσης και όχι στις μεθόδους που ανήκουν στην παραγόμενη κλάση. Basic Class ProdA Class Basic Class ProdA Class Object Object 97

Constructor στην παραγομένη κλάση Αν και μπορούμε να χρησιμοποιήσουμε τον constructor δίχως όρισμα της βασικής κλάσης για να αρχικοποιήσουμε ένα αντικείμενο της παραγόμενης κλάσης, το ίδιο δεν μπορεί να συμβεί σε constructor με όρισμα της βασικής κλάσης. Σε αυτή την περίπτωση φτιάχνουμε constructors με όρισμα και χωρίς όρισμα και στην παραγόμενη κλάση. Έτσι για αρχικοποίηση από την παραγόμενη κλάση καλούμε τον constructor της βασικής. 98

Παράδειγμα constructor βασικής και παραγόμενης κλάσης ΠΑΡΑΓΟΜΕΝΗ ΒΑΣΙΚΗ class Produced:public Basic { public: Produced():Basic() {} Produced(float temp):basic(temp) {} Constructor ΧΩΡΙΣ ΟΡΙΣΜΑ ΤΗΣ ΠΑΡΑΓΟΜΕΝΗΣ Constructor ΜΕ ΟΡΙΣΜΑ ΤΗΣ ΠΑΡΑΓΟΜΕΝΗΣ Constructor ΧΩΡΙΣ ΟΡΙΣΜΑ ΤΗΣ ΒΑΣΙΚΗΣ Constructor ΜΕ ΟΡΙΣΜΑ ΤΗΣ ΒΑΣΙΚΗΣ 99

Επεξήγηση παραδείγματος Όταν στην main() φτιάξουμε ένα αντικείμενο της παραγόμενης χωρίς όρισμα δηλ. το Produced Pr1; τότε εκτελείται η εντολή: Produced():Basic(). Ο constructor Produced() καλεί τον constructor Basic() για την αρχικοποίηση του Pr1. Αντίστοιχα εάν φτιάξουμε ένα αντικείμενο με όρισμα δηλ. το Produced Pr2(20,5); Τότε εκτελείται η εντολή: Produced(float temp):basic(temp) όπου καλείται ο constructor Produced(float temp) με όρισμα και αυτός καλεί τον constructor Basic(temp) με όρισμα και του μεταβιβάζει την παράμετρο temp για να αρχικοποιηθεί το αντικείμενο Pr2. 100

Υπερφόρτωση συναρτήσεων μελών Μπορούμε μέσα σε μία παραγόμενη κλάση να φτιάξουμε συναρτήσεις μέλη που έχουν το ίδιο όνομα με κάποιες στην βασική κλάση. Με αυτόν τον τρόπο μπορούμε να χρησιμοποιούμε για έλεγχο τις συναρτήσεις των παραγομένων κλάσεων χωρίς να πειράζουμε τον κώδικα των συναρτήσεων της βασικής κλάσης. Αυτή η διαδικασία ονομάζεται υπερφόρτωση συναρτήσεων. Είναι πολύ σημαντικό να γνωρίζουμε ότι μέσα στην μέθοδο της παραγόμενης κλάσης για να καλέσουμε την αντίστοιχη με το ίδιο όνομα της βασικής κλάσης, θα πρέπει να χρησιμοποιούμε τον τελεστή διάκρισης εμβέλειας ( :: ), γιατί αλλιώς η μέθοδος καλεί τον εαυτό της με όχι και τόσο επιθυμητά αποτελέσματα για το πρόγραμμα. 101

Σύνταξη υπερφόρτωσης class Prod:public Basic { Public: void funca(orisma) { If (orisma!=0) Basic::funcA(orisma); else } Δημιουργία συνάρτησης στην παραγόμενη κλάση με το ίδιο όνομα με την συνάρτηση της βασικής Έλεγχος Χρήση της συνάρτησης της βασικής κλάσης (υπερφόρτωση) 102

Επεξήγηση παραδείγματος υπερφόρτωσης Στο παραπάνω παράδειγμα φτιάχνουμε μια συνάρτηση: funca(orisma) που υπάρχει και στην βασική με το ίδιο όνομα και καλούμε μέσα σε αυτήν την συνάρτηση της βασικής, για να της περάσουμε την τιμή του ορίσματος μετά από κάποιον έλεγχο. Η συνάρτηση funca() της βασικής μπορεί να κάνει κάτι παρόμοιο με την αντίστοιχη της παραγόμενης ή κάτι διαφορετικό. 103

Επίπεδα κλάσεων Μια κλάση μπορεί να παραχθεί από μια άλλη κλάση που είναι και αυτή παραγόμενη. Δηλ. class Basic {}; class ProdA:public Basic {}; class ProdB:public ProdA {}; ProdB ProdA ProdC Η κλάση ProdB είναι δημόσια παραγόμενη από την κλάση ProdA, που με την σειρά της είναι δημόσια παραγόμενη από την βασική κλάση Basic. 104

Πολλαπλή κληρονομικότητα Μια κλάση μπορεί να παραχθεί από περισσότερες από μια βασικές κλάσεις. class FrstClass {}; class ScndClass {}; class PrdClass:public FrstClass, public ScndClass {}; FrstClass ScndClass Η κλάση PrdClass παράγεται δημόσια από τις κλάσεις FrstClass και ScndClass, οι οποίες έχουν πρωτίστως οριστεί. 105

Περιεκτικότητα Μια άλλη σχέση που μπορεί να υπάρξει μεταξύ δύο κλάσεων εκτός από την κληρονομικότητα είναι η περιεκτικότητα όπου ένα αντικείμενο μιας κλάσης περιέχεται σε μια άλλη κλάση. Π.χ: class Basic_Class {}; class Other_Class { Basic_Class Bas1; Private: }; ΑΝΤΙΚΕΙΜΕΝΟ ΚΛΑΣΗΣ ΣΤΗΝ ΚΛΑΣΗ ΤΗΣ ΜΕΣΑ 106

107

Τι είναι υπερφόρτωση τελεστών Η ιδιότητα με την οποία στην C++ μπορούμε να έχουμε τελεστές που να ενεργούν διαφορετικά μέσα στο ίδιο πρόγραμμα την ονομάζουμε υπερφόρτωση. Το χαρακτηριστικό αυτό της C++ δηλαδή την διαφορετική χρησιμοποίηση των τελεστών μέσα στο ίδιο πρόγραμμα το λέμε πολυμορφισμό. Άρα Μία γλώσσα προγραμματισμού είναι αντικειμενοστραφής όταν συνδυάζει τα χαρακτηριστικά των κλάσεων-αντικειμένων, της κληρονομικότητας και του πολυμορφισμού. 108

Γιατί χρειαζόμαστε την υπερφόρτωση τελεστών Οι τελεστές π.χ. +, -, *, /, <<, ==, <, >,!= κ.τ.λ. όπως τους ξέρουμε ενεργούν μόνο επάνω σε μεταβλητές. Π.χ: z=x+y ή a+=b*c ή i<j Τι γίνεται όμως όταν έχουμε αντικείμενα; Δηλ: log3 = log1 + log2 εδώ ο compiler θα εντοπίσει λάθος. Εδώ θα χρειαστούμε την ιδιότητα της υπερφόρτωσης τελεστών. 109

Υπερφόρτωση του τελεστή << (1) Ο τελεστής << ξέρουμε ότι είναι αυτός που μαζί με τα αντικείμενα cin και cout καθορίζει την ροή εισόδου ή εξόδου των δεδομένων στην C++. Μπορεί επίσης με υπερφόρτωση να ενεργήσει σε δύο ακέραιους και να μετακινήσει τα δυαδικά τους ψηφία προς τα αριστερά. Δηλαδή στην έκφραση: 3 << 2 Μετακινεί προς τα αριστερά τα δυαδικά ψηφία του ακέραιου που βρίσκεται στα αριστερά του (δηλαδή του ακέραιου 3) τόσες θέσεις όσες ορίζει ο ακέραιος που βρίσκεται στα δεξιά του (δηλαδή 2 θέσεις). 110

Υπερφόρτωση του τελεστή << (2) Εξετάζοντας το προηγούμενο παράδειγμα βλέπουμε ότι στο δυαδικό σύστημα ο δεκαδικός αριθμός 3 γράφεται 11. Εάν ο 11 μετακινηθεί κατά δύο θέσεις στα αριστερά όπως του ορίζει ο αριθμός 2, τα κενά που θα προκύψουν δεξιά του αριθμού συμπληρώνονται από δύο μηδενικά, άρα ο αριθμός γίνεται 1100. Ο δυαδικός αριθμός 1100 που προέκυψε τώρα είναι ο δεκαδικός αριθμός 12. Ο δυαδικός αριθμός 12 προκύπτει από την παράσταση: 1*2 3 + 1*2 2 + 0*2 1 + 0*2 0 = 8 + 4 + 0 + 0 = 12 111

Άλλο ένα παράδειγμα υπερφόρτωσης του << (1) -2<<4 Εξετάζοντας αυτό το παράδειγμα βλέπουμε ότι στο δυαδικό σύστημα ο δεκαδικός αριθμός -2 γράφεται 10000010 όπου το πρώτο 1 ορίζει ότι ο αριθμός είναι αρνητικός. Εάν μετακινηθεί κατά τέσσερις θέσεις στα αριστερά όπως του ορίζει ο δεξιός τελεστέος, τα κενά που θα προκύψουν δεξιά του αριθμού συμπληρώνονται από τέσσερα μηδενικά, άρα ο αριθμός γίνεται 1010000. Ο δυαδικός αριθμός 1010000 που προέκυψε τώρα είναι ο δεκαδικός αριθμός -32. 112

Τελεστές αύξησης ++ και μείωσης -- ως μετρητές Πιο κάτω εξηγείται η λειτουργία μεταβλητών ως τελεστές αύξησης και μείωσης κατά 1: ++i; Η τιμή της μεταβλητής i αυξάνει κατά 1 και μετά χρησιμοποιείται. Πρώτα χρησιμοποιείται η τιμή της μεταβλητής i και μετά αυξάνεται κατά 1. i++; --i; Η τιμή της μεταβλητής i μειώνεται κατά 1 και μετά χρησιμοποιείται. i--; Πρώτα χρησιμοποιείται η τιμή της μεταβλητής i και μετά μειώνεται κατά 1. 113

Οι τελεστές ανάθεσης τιμής += και -= Οι τελεστές + και - χρησιμοποιούνται επίσης για αύξηση και μείωση τιμών των μεταβλητών ως ακολούθως: x+=y; η τιμή της μεταβλητής x αυξάνεται κατά y ή αλλιώς x=x+y; x-=y; η τιμή της μεταβλητής x μειώνεται κατά y ή αλλιώς x=x-y; x+=y*z; η τιμή της μεταβλητής x αυξάνεται κατά y*z ή αλλιώς x=x+(y*z) και όχι x=(x+y)*z; 114

Τελεστές με αντικείμενα (1) Τι γίνεται όμως όταν έχουμε αντικείμενα; Μπορούμε δηλαδή: Να αυξήσουμε την τιμή ενός αντικειμένου; (++log1)ή Να κάνουμε πράξεις με τις τιμές αντικειμένων; (log3=log1+log2) για να το κάνουμε αυτό πρέπει να χρησιμοποιήσουμε στην συνάρτηση που θα χρειαστεί να αυξήσει τιμή στο αντικείμενο, την λέξη κλειδί operator. 115

Τελεστές με αντικείμενα (2) Η λέξη αυτή επεκτείνει την χρήση του εκάστοτε τελεστή (++, --, +, - κλπ) από τις μεταβλητές και στα αντικείμενα. Με την λέξη operator φτιάχνουμε συνάρτηση αύξησης ή μείωσης της τιμής. Υπάρχουν δύο μορφές χρήσης του operator, η προθεματική όπου ο τελεστής βρίσκεται αριστερά από το δεδομένο-μέλος και η επιθεματική όπου ο τελεστής βρίσκεται δεξιά από το δεδομένομέλος. Τις δύο μορφές τις αναλύουμε παρακάτω. 116

Προθεματική χρήση του operator Εάν έχουμε προθεματική μορφή τελεστή (++i) τότε ο operator γίνεται: void operator ++() { } ++i; Τώρα στο αντικείμενο που θα φτιάξουμε θα εφαρμόσουμε κατευθείαν επάνω του τον τελεστή ++ χωρίς να υπάρξει λάθος του compiler δηλ. ++log1; 117

Επιθεματική χρήση του operator Εάν έχουμε επιθεματική μορφή τελεστή (i++) τότε ο operator γίνεται: void operator ++(int) { } i++; Το int μέσα στην παρένθεση δεν σημαίνει ότι υπάρχει ακέραιος αριθμός, αλλά κάνει τον compiler να ξεχωρίσει πως θα χρησιμοποιήσει τον operator. Μπορούμε τώρα να εφαρμόσουμε τον τελεστή ++ πάνω στο αντικείμενο δηλ log1++; 118

Υπερφόρτωση του τύπου x+=y Κάπως έτσι μπορούμε να χρησιμοποιήσουμε υπερφόρτωση του τελεστή ανάθεσης τιμής με την χρήση του operator ως εξής: void operator ++() { } i+=2; 119

Υπερφόρτωση του τελεστή άθροισης + (1) Για να μπορέσουμε να προσθέσουμε αντικείμενα δηλ. log3=log1+log2; θα πρέπει να χρησιμοποιήσουμε τον πιο κάτω κώδικα: logariasmos operator+ (logariasmos log) { logariasmos temp; temp.ypoloipo=ypoloipo+log.ypoloipo; return temp; } 120

Υπερφόρτωση του τελεστή + (2) Τώρα μπορούμε να προχωρήσουμε στην αρχική έκφραση και να προσθέσουμε τις τιμές των αντικειμένων σαν να προσθέτουμε απλές μεταβλητές. Η συνάρτηση έχει την τιμή του log1 και το όρισμα μέσα στην παρένθεση είναι το log2. 121

Υπερφόρτωση συγκριτικού τελεστή > Μπορούμε με το ίδιο σκεπτικό να υπερφορτώσουμε και συγκριτικούς τελεστές. H πρακτική αυτή μας βοηθά να συγκρίνουμε απευθείας τιμές αντικειμένων μέσα στην main δηλ. log1>log2 bool operator > (logariasmos log) { } if(ypoloipo>log.ypoloipo) else return true return false 122

Υπόλοιποι τελεστές Κατά αντιστοιχία γίνεται υπερφόρτωση και των υπολοίπων τελεστών. Δηλαδή για τους δυαδικούς: Ο τελεστής >> όπως ο τελεστής << για τους αριθμητικούς: Ο τελεστής -- όπως ο τελεστής ++ Ο τελεστής - όπως ο τελεστής + για τους συγκριτικούς: Ο τελεστής < όπως ο τελεστής > Ο τελεστής =! όπως ο τελεστής == Επίσης υπερφορτώνεται και ο τελεστής κλήσης συνάρτησης () 123

Ποιοι τελεστές δεν υπερφορτώνονται Όλοι οι τελεστές μπορούν να υπερφορτωθούν εκτός από τους παρακάτω: 124

Περιορισμοί της υπερφόρτωσης τελεστών (1) Με την υπερφόρτωση δεν αλλάζει: o η προτεραιότητα του τελεστή, o η προσεταιριστικότητα του τελεστή, o το πλήθος των τελεστέων που δέχεται ο τελεστής (π.χ. ο δυαδικός δέχεται πάντα δύο τελεστέους), o η σημασία του τρόπου λειτουργίας του τελεστή (π.χ ο τελεστής * πολλαπλασιάζει δύο τελεστέους και αυτό δεν αλλάζει). Δεν μπορούμε να δημιουργήσουμε καινούριους τελεστές για να τους υπερφορτώσουμε (χρησιμοποιούμε μόνο τους ήδη υπάρχοντες). 125

Περιορισμοί της υπερφόρτωσης τελεστών (2) Τους συναφείς τελεστές π.χ + και += τους υπερφορτώνουμε ξεχωριστά (δηλ. σε διαφορετικές συναρτήσεις υπερφόρτωσης). Οι συναρτήσεις υπερφόρτωσης μπορεί και να μην είναι μέλη κλάσεων (δηλ. μπορούν να δηλώνονται αυτόνομες μέσα στο πρόγραμμα). Οι συναρτήσεις υπερφόρτωσης των τελεστών (), [], -> πρέπει οπωσδήποτε να είναι μέλη κλάσεων. 126

127

Τι είναι οι δείκτες Οι δείκτες είναι μεταβλητές που δεν έχουν δικές τους τιμές, αλλά αναφέρονται (δείχνουν) σε άλλες μεταβλητές και χρησιμοποιούν τις τιμές τους. Η αναφορά σε μία άλλη μεταβλητή γίνεται με βάση την διεύθυνση που έχει στην μνήμη η μεταβλητή αυτή. Ένας δείκτης λοιπόν έχει ως περιεχόμενο την διεύθυνση της μεταβλητής, άρα έχει έμμεση πρόσβαση στην τιμή της μεταβλητής αφού αναφέρεται στην διεύθυνσή της. Άρα μια μεταβλητή αναφέρεται άμεσα σε μία τιμή ενώ ένας δείκτης αναφέρεται έμμεσα σε μια τιμή. 128

Δήλωση δεικτών Έστω ότι έχουμε ορίσει την μεταβλητή int a; Η οποία έχει την τιμή 20. Ο δείκτης γι αυτήν την μεταβλητή ορίζεται με τον ίδιο τύπο και με τον τελεστή έμμεσης διευθυνσιοδότησης * πριν το όνομά του δηλ: int *ptr; Για να του δώσουμε την διεύθυνση της μεταβλητής χρησιμοποιούμε τον τελεστή διεύθυνσης & δηλ: ptr=&a; Τώρα ο δείκτης ptr δείχνει στην διεύθυνση της μεταβλητής a. Εάν τώρα γράψουμε *ptr ο δείκτης παίρνει το περιεχόμενο της a δηλ. το 20. 129

Σχηματική παράσταση 2124 a=20; Απόδοση τιμής στη μεταβλητή 2126 20 a int a; Δήλωση μεταβλητής 2128 *ptr ---- ptr=&a Απόδοση διεύθυνσης της a ---- 2200 2126 ptr int *ptr; Δήλωση δείκτη *ptr; Απόδοση περιεχομένου της a 130

Κώδικας του προηγούμενου παραδείγματος include <iostream.h> void main() { int a; // δήλωση μεταβλητής a int *ptr; // δήλωση δείκτη ptr a=20; // η τιμή της a=20 &a; // η διεύθυνση της a=0xfff4 ptr=&a; // η διεύθυνση του ptr=0xfff4 *ptr; // η τιμή του ptr=20 } 131

Εκφράσεις και Πράξεις με δείκτες (1) Οι δείκτες μπορούν να χρησιμοποιηθούν σε αριθμητικές πράξεις μέσα σε εκφράσεις αλλά και σε συγκρίσεις. Οι τιμές που χρησιμοποιούν δεν είναι δικές τους αλλά ανήκουν στις μεταβλητές στις οποίες αναφέρονται (που δείχνουν). Στην επόμενη διαφάνεια φαίνεται ένα παράδειγμα πράξεων μεταβλητών αλλά και δεικτών. 132

Εκφράσεις και Πράξεις με δείκτες (2) int a, b, c, d *ptr1, *ptr2; a=5; b=10; //έκφραση με πράξεις μεταξύ μεταβλητών c=a*b+a/(b-a); // η c έχει τιμή 11 ptr1=&a; // η διεύθυνση της a πάει στον ptr1 ptr2=&b; // η διεύθυνση της b πάει στον ptr2 //έκφραση με πράξεις μεταξύ δεικτών d=(*ptr1)*(*ptr2)+(*ptr1)/((*ptr2)-(*ptr1)); // η d έχει τιμή 11 133

Κανόνες χρήσης δεικτών Εκφράσεις και Πράξεις με δείκτες (3) Στους δείκτες εφαρμόζουμε τους αριθμητικούς τελεστές αύξησης κατά ένα ++, μείωσης κατά ένα --, πρόσθεσης ακεραίου + ή +=, αφαίρεσης ακεραίου η -=. Εκχώρηση ενός δείκτη σε έναν άλλο γίνεται μόνο εάν είναι και οι δύο του ίδιου τύπου. Σε αντίθετη περίπτωση γίνεται πρώτα μετατροπή τύπου. Εξαιρείται ο δείκτης void * ο οποίος δέχεται δείκτη οποιουδήποτε τύπου, αλλά με την σειρά του εκχωρείται σε δείκτη άλλου τύπου μετά από μετατροπή. 134

Εκφράσεις και Πράξεις με δείκτες (4) Μπορούμε να συγκρίνουμε δείκτες με τελεστές ισότητας ή συγκριτικούς τελεστές μόνο εάν οι δείκτες δείχνουν σε μεταβλητές ίδιου τύπου. Χρησιμοποιούμε αριθμητικές πράξεις δεικτών που βρίσκονται μέσα σε πίνακες αλλά και σε δείκτες που δείχνουν αντικείμενα. 135

Χρήση του δείκτη σε πολλές μεταβλητές Μπορεί ένας δείκτης να πάρει τις τιμές πολλών μεταβλητών, μία κάθε φορά. Αυτό γίνεται εάν αλλάζουμε την διεύθυνση στην οποία δείχνει ο δείκτης. Δηλ.: int a=3, b=2; int *ptr; p=&a; //o ptr δείχνει στην a *ptr; //παίρνει την τιμή της a (τιμή 3) ptr=&b; // o ptr τώρα δείχνει στην b *ptr; //τώρα παίρνει την τιμή της b (τιμή 2) 136

Ο δείκτης αλλάζει την τιμή της μεταβλητής Ένας δείκτης μπορεί να αλλάξει την τιμή της μεταβλητής στην οποία αναφέρεται αν στο *prt δώσουμε νέα τιμή. Δηλ.: int a, *ptr; a=10; //η a έχει τιμή 10 ptr=&a; // αναφορά του ptr στην a *ptr // το *ptr έχει την τιμή της a. *ptr=12; /* αλλάζει η τιμή του ptr αλλά και της μεταβλητής a που δείχνει. */ 137

Δείκτες και πίνακες (1) Έστω ο πιο κάτω πίνακας ακεραίων ar[5] 1000 1002 1004 1006 1008 22 3 102 10 12 ar[0] ar[1] ar[2] ar[3] ar[4] 138

Δείκτες και πίνακες (2) Αν γράψουμε ptr=&ar[0]; o δείκτης prt παίρνει την διεύθυνση του πρώτου στοιχείου του πίνακα ar[]. και αν γράψουμε: *ptr; Τότε ο δείκτης prt έχει το περιεχόμενο 22, δηλ. την τιμή του στοιχείου ar[0]. 139

Δείκτες και πίνακες (3) Εάν θέλουμε να δείξουμε στον επόμενο στοιχείο του πίνακα απλά γράφουμε ptr++;. Εάν θέλουμε να δείξουμε στο τρίτο στοιχείο του πίνακα γράφουμε ptr+=2; Βλέπουμε ότι ένας δείκτης μπορεί να λειτουργεί και σαν μετρητής. Για την διεύθυνση του prt γράφουμε: ptr=&ar[0]+i [όπου i=0,1,2,3,4] Ο ptr θα πάρει διαδοχικά τις τιμές: 1000, 1002, 1004, 1006, 1008 που είναι και οι διευθύνσεις των στοιχείων του πίνακα ar[]. Αυτό θα γίνει με την χρήση ενός βρόχου for. 140

Δείκτες και συμβολοσειρές Γνωρίζουμε ότι οι συμβολοσειρές είναι ουσιαστικά μονοδιάστατοι πίνακες τύπου char. Η συμβολοσειρά λοιπόν POINTER μπορεί να δηλωθεί ως εξής: char ca[7]= POINTER ; Ας ορίσουμε τώρα και έναν δείκτη τύπου char δηλ.: char *ptrch; Mε την δήλωση: ptrch=&ca[0]; ή ptrch=&ca; o δείκτης δείχνει στον πρώτο χαρακτήρα της συμβολοσειράς δηλαδή στο P. Εάν αυξήσουμε κατάλληλα την τιμή του ptrch αυτός θα μας δείξει τον επόμενο χαρακτήρα ή οποιονδήποτε χαρακτήρα ή μια ομάδα χαρακτήρων από την συμβολοσειρά. 141

ΚΛΗΣΗ ΜΕ ΤΙΜΗ Δείκτες και συναρτήσεις (1) Μάθαμε ότι όταν χρησιμοποιούμε συναρτήσεις για υπολογισμούς, μέσα στις παρενθέσεις της συνάρτησης βάζουμε παραμέτρους ή αλλιώς τοπικές μεταβλητές, που σκοπό έχουν να πάρουν αντίγραφα των τιμών των αρχικών μεταβλητών του προγράμματος και να εκτελέσουν τους υπολογισμούς. Αυτή η διαδικασία ονομάζεται κλήση με τιμή. Οι τιμές των αρχικών μεταβλητών δεν επηρεάζονται από την συνάρτηση. 142

Δείκτες και συναρτήσεις (2) ΚΛΗΣΗ ΜΕΣΩ ΑΝΑΦΟΡΑΣ ΜΕ ΔΕΙΚΤΗ Με την χρήση δεικτών στην θέση των παραμέτρων μίας συνάρτησης, μπορούμε να δούμε εκτός από τις τιμές και την διεύθυνση των μεταβλητών, καθώς οι δείκτες δείχνουν απευθείας στο περιεχόμενο της αρχικής μεταβλητής. Ως ετούτου μπορούμε να αλλάξουμε τις τιμές στις αρχικές μεταβλητές ή να επιστρέφουμε με το return παραπάνω από μία τιμές. Αυτή η διαδικασία ονομάζεται κλήση μέσω αναφοράς με δείκτη. 143

Διαχείριση μνήμης Όταν θέλουμε να αποθηκεύσουμε πολλά στοιχεία, χρησιμοποιούμε πίνακες που είμαστε υποχρεωμένοι να γνωρίζουμε το μέγεθός τους (πόση μνήμη θα δεσμεύσουμε) και να το καθορίσουμε πριν από την εκτέλεση του προγράμματος. Όταν δεν γνωρίζουμε εκ των προτέρων πόση μνήμη θα χρειαστούμε, χρησιμοποιούμε τους τελεστές new και delete για να δεσμεύσουμε και να αποδεσμεύσουμε τμήματα μνήμης κατά την εκτέλεση του προγράμματος. Αυτό σημαίνει ότι παρόλο που έχουμε δηλώσει στο πρόγραμμα τους τελεστές αυτούς, η μνήμη θα δεσμευθεί όταν το πρόγραμμα εκτελεστεί και όχι από την αρχή όπως συμβαίνει με τους πίνακες. 144

Οι τελεστές new-delete Ο τελεστής new επιστρέφει έναν δείκτη για τον κατάλληλο τύπο δεδομένων δεσμεύοντας ταυτόχρονη την μνήμη που θα χρειαστεί. Ο τελεστής delete αποδεσμεύει τον χώρο στην μνήμη που έχει δεσμεύσει ο new επιστρέφοντας την μνήμη στο σύστημα. Ο τρόπος με τον οποίο λειτουργούν αυτοί οι τελεστές λέγεται δυναμική ανάθεση μνήμης. 145

Παράδειγμα με τελεστές new-delete (1) Ας υποθέσουμε ότι έχουμε τις πιο κάτω γραμμές κώδικα. int size; float *array; //dhlwsh deikth cin>>size; //mege8os pinaka //o deikths deixnei ston pinaka array=new float[size]; Σε αυτό το παράδειγμα δηλώνουμε έναν δείκτη *array ως τύπο float και μετά βάζουμε τον δείκτη να δείχνει στον πίνακα τύπου float με πλήθος στοιχείων size. 146

Παράδειγμα με τελεστές new-delete (2) Εάν οι εντολές αυτές δεν εκτελούνται εξ αρχής διότι μπορεί να βρίσκονται μέσα σε μία if που να τους επιτρέπει να εκτελεστούν με την επαλήθευση κάποιας συνθήκης, τότε δεν δεσμεύεται μνήμη για τον πίνακα. Ο τελεστής delete για την αποδέσμευση της μνήμης μπαίνει στο τέλος της χρήσης του πίνακα, με τις γωνιακές αγκύλες να τοποθετούνται μετά από το delete (η αλλιώς πριν τον πίνακα). Delete [] array; 147

Δείκτες και αντικείμενα (1) Οι δείκτες μπορούν να δείχνουν και σε αντικείμενα. Αν δεν γνωρίζουμε εξ αρχής πόσα αντικείμενα θα δημιουργήσουμε, με την χρήση του τελεστή new επιστρέφουμε έναν δείκτη σε ένα ανώνυμο αντικείμενο. Π.χ. cat *c; //dhlwsh deikth thw klashs cat // o deikths deixnei se ena anwnymo // antikeimeno ths klashs cat c=new cat; 148

Δείκτες και αντικείμενα (2) Κατά την εκτέλεση του προγράμματος μπορούμε να δημιουργήσουμε όσα αντικείμενα θέλουμε. Για να καλέσει το αντικείμενο μέσω του δείκτη τις συναρτήσεις μέλη, χρησιμοποιούμε τον τελεστή προσπέλασης μέλους -> Δηλ. c->readdata(); 149

Πίνακας δεικτών Μπορούμε όταν έχουμε να δημιουργήσουμε πολλά αντικείμενα σε ένα πρόγραμμα, αντί να βάλουμε τα ίδια τα αντικείμενα σε έναν πίνακα (πίνακας αντικειμένων), να φτιάξουμε έναν πίνακα δεικτών που να δείχνουν τα αντικείμενα. Π.χ. cat *c_arr[10]; //pinakas deiktwn //o pinakas deixnei sthn klash cat c_arr[i]= new cat; //klhsh synarthshs apo ta antikeimena ths klashs c_arr[i]->printdata(); 150

151

Τι είναι αρχείο Οι πληροφορίες που καλείται να διαχειριστεί ο Η/Υ είναι τόσες πολλές, που η μνήμη του δεν φτάνει να τις επεξεργαστεί όλες μαζί. Γι αυτό τον λόγο τις αποθηκεύουμε σε μονάδες αποθήκευσης (π.χ hdd, cd, dvd) με την μορφή αρχείων. Τα αρχεία είναι ένα σύνολο τιμών του ίδιου τύπου. Μήκος του αρχείου είναι ο αριθμός των στοιχείων του. Το κενό αρχείο έχει μήκος 0 (μηδέν) Παραδείγματα: 1. το (5, -3, 34, -23, 7) είναι ένα αρχείο τύπου int μήκους 5 και 2. το ( s, /, a, S, @, o, *, _ ) είναι τύπου char μήκους 8. 152

Μορφοποίηση Τα αρχεία που περιέχουν χαρακτήρες, όπως το παράδειγμα 2 στην προηγούμενη διαφάνεια, ονομάζονται αρχεία κειμένου ή μορφοποιημένα αρχεία και μπορούν να διαβαστούν εύκολα από έναν κειμενογράφο. Τα αρχεία που περιέχουν αριθμητικές τιμές, όπως το παράδειγμα 1 που μπορεί να έχουν προκύψει από επεξεργασία τιμών και εκφράσεων από τον υπολογιστή, ονομάζονται δυαδικά αρχεία ή μη μορφοποιημένα αρχεία. Τα αρχεία αυτά διαβάζονται από ειδικά προγράμματα. 153

Δημιουργία αρχείων (1) Για να δημιουργήσουμε ένα αρχείο πρέπει πρώτα να φτιάξουμε ένα ρεύμα (stream) από το αρχείο προς το πρόγραμμα και από το πρόγραμμα προς το αρχείο, κατόπιν να βρούμε την αρχή του αρχείου και τέλος να ανοίξουμε (open) το ρεύμα του αρχείου. 154

Δημιουργία αρχείων (2) Για το σκοπό αυτό χρησιμοποιούμε την κλάση fstream (file stream) του αρχείου κεφαλίδας fstream.h η οποία ανοίγει ρεύματα διπλής κατεύθυνσης και κληρονομεί χαρακτηριστικά από την κλάση iostream καθώς και από την υπερκλάση ios. Στην αρχή του κώδικα θα πρέπει να συμπεριλάβουμε το αρχείο κεφαλίδας fstream.h με την δήλωση: #include <fstream.h> Στο αρχείο κεφαλίδας fstream.h υπάρχουν επίσης και οι κλάσεις: ifstream (input file stream) για ρεύματα από το αρχείο προς το πρόγραμμα και 155

Δημιουργία αρχείων (3) ofstream (output file stream) για ρεύματα από το πρόγραμμα προς το αρχείο. 156