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

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

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

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

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

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

Πρότυπα και διανύσματα

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

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ EPL035: ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΚΑΙ ΑΛΓΟΡΙΘΜΟΙ

Συλλογές, Στοίβες και Ουρές

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

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

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

Αλγόριθμοι και Δομές Δεδομένων (IΙ) (γράφοι και δένδρα)

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

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

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

Τύποι Δεδομένων και Απλές Δομές Δεδομένων. Παύλος Εφραιμίδης V1.0 ( )

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

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

Δομές Δεδομένων (Data Structures)

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

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

Διάλεξη 05: Αφηρημένοι Τύποι Δεδομένων

ΠΑΡΑΡΤΗΜΑ: QUIZ ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ

Δομές Δεδομένων και Αλγόριθμοι

Μάθημα 22: Δυαδικά δέντρα (Binary Trees)

ΕΠΛ231 Δομές Δεδομένων και Αλγόριθμοι 5. Αφηρημένοι Τύποι Δεδομένων / Στοίβες και Ουρές

POINTERS, AGGREGATION, COMPOSITION

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

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

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

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

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

Βασικές Έννοιες Δοµών Δεδοµένων

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

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

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

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

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

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

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ Η/Υ ΠΡΩΤΗ ΠΡΟΟΔΟΣ ΣΤΗΝ «ΟΡΓΑΝΩΣΗ ΚΑΙ ΣΧΕΔΙΑΣΗ Η/Y»

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

Στοίβες - Ουρές. Στοίβα (stack) Γιάννης Θεοδωρίδης, Νίκος Πελέκης, Άγγελος Πικράκης Τµήµα Πληροφορικής

#define, 70, 575 #elif, 580 #else, 580 #endif, 580 #error, 584 #if, 580 #ifdef, 583 #ifndef, 580, 583 #include, 70, 227, 574 #undef, 579

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

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

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

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

Διάλεξη 12: Δέντρα ΙΙ Δυαδικά Δέντρα

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

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

Κατ οίκον Εργασία 3 Σκελετοί Λύσεων

AVL-trees C++ implementation

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

Προγραμματισμός Αναδρομή

Δοµές Δεδοµένων. 6η Διάλεξη Αναδροµικές Εξισώσεις και Αφηρηµένοι Τύποι Δεδοµένων. Ε. Μαρκάκης

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

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

Προγραμματισμός Αναδρομή

Δομές δεδομένων (2) Αλγόριθμοι

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

Διασυνδεδεμένες Δομές. Δυαδικά Δέντρα. Προγραμματισμός II 1

Περιεχόμενα. Λίγα λόγια για αυτή την έκδοση... 23

Διάλεξη 16: Σωροί. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Ουρές Προτεραιότητας - Ο ΑΤΔ Σωρός, Υλοποίηση και πράξεις

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

ΕΡΓΑΣΤΗΡΙΟ 5 ΣΗΜΕΙΩΣΕΙΣ

Εργαστήριο 8: Αναδρομική διεργασία εισαγωγής καινούριου κόμβου σε ΔΔΑ

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

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

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

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

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

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

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

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

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

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (2)

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

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

Γλώσσα Προγραμματισμού C++ Εισαγωγή - Μια πρώτη ματιά

Απλές Δοµές Δεδοµένων Στην ενότητα αυτή θα γνωρίσουµε ορισµένες απλές Δοµές Δεδοµένων και θα τις χρησιµοποιήσουµε για την αποδοτική επίλυση του προβλή

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

Αναδροµή. Σε αυτήν την (βοηθητική) ενότητα θα µελετηθούν τα εξής : Η έννοια της αναδροµής Υλοποίηση και αποδοτικότητα Αφαίρεση της αναδροµής

ΗΥ240: Δομές Δεδομένων Εαρινό Εξάμηνο Ακαδημαϊκό Έτος 2017 Διδάσκουσα: Παναγιώτα Φατούρου Προγραμματιστική Εργασία - 2o Μέρος

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

Διορθώσεις σελ

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

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

Αλγόριθμοι Τυφλής Αναζήτησης

Εντολές εισόδου - εξόδου. Εισαγωγή στη C++

Αναδρομή Ανάλυση Αλγορίθμων

Initialize each person to be free. while (some man is free and hasn't proposed to every woman) { Choose such a man m w = 1 st woman on m's list to

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

Διάλεξη 16: Σωροί. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Ουρές Προτεραιότητας - Ο ΑΤΔ Σωρός, Υλοποίηση και πράξεις

Στόχοι και αντικείμενο ενότητας. Εκφράσεις. Η έννοια του τελεστή. #2.. Εισαγωγή στη C (Μέρος Δεύτερο) Η έννοια του Τελεστή

Δομές Δεδομένων & Ανάλυση Αλγορίθμων. 3ο Εξάμηνο. Ουρά (Queue) Υλοποίηση της με τη βοήθεια πίνακα.

ιαφάνειες παρουσίασης #11

Επίλυση Προβλημάτων 1

Εργαστήριο 2ο. Περίγραμμα Εργαστηριακής Άσκησης

Διάλεξη 15: Αναδρομή (Recursion) Διδάσκων: Παναγιώτης Ανδρέου

Transcript:

ΣΧΕΔΙΟΤΥΠΑ (TEMPLATES) Γεώργιος Παπαϊωάννου (2013-14) gepap@aueb.gr

Περιγραφή: Τι είναι τα σχεδιότυπα και που μας εξυπηρετούν Template συναρτήσεις Template κλάσεις Εξειδίκευση σχεδιοτύπων Σχεδιότυπα και αρχεία.h kai.cpp/c++ Παραδείγματα χρήσης σχεδιοτύπων Τελευταία ενημέρωση: Σεπτέμβριος 2013 Εισαγωγή - 2

void myswap(int& a, int& b) const int temp = a; a = b; b = temp; void myswap(float& a, float& b) const float temp = a; a = b; b = temp; void myswap(string& a, string& b) const string temp = a; a = b; b = temp;... Εναλλακτικά: Αντί να ορίσουμε ξεχωριστές μορφές της συνάρτησης, καθορίζουμε πώς μπορεί να παραχθεί μια μορφή της για οποιονδήποτε τύπο Τ: template <typename T> void myswap(t& a, T& b) const T temp = a; a = b; b = temp; 3

template <typename T> void myswap(t& a, T& b) // Το σχεδιότυπο απαιτεί και τα δύο const T temp = a; // ορίσματα να είναι του ιδίου τύπου Τ. a = b; b = temp; int main() int i = 10, j = 20; myswap(i, j); // Παράγεται αυτόματα η κατάλληλη συνάρτηση. cout << i << << j; // Τυπώνει: «20, 10». string s1= "hi", s2 = there"; myswap(s1, s2); // Παράγεται άλλη μορφή της συνάρτησης. cout << s1 << s2 <<; // Τυπώνει: «there», «hi». myswap(i, s1); // Λάθος: ορίσματα διαφορετικών τύπων. // Δεν έχουμε σχεδιότυπο για αυτή την // περίπτωση (διαφορετικοί τύποι). 4

template <typename T1, typename T2> void printfirstpairs( const unsigned int n, const vector<t1>& v1, const vector<t2>& v2) for( unsigned i = 0; i < v1.size() && i < v2.size() && i < n; i++) int main() cout << i << ": " << v1[i] << ", " << v2[i] << endl; vector<string> vec1; vector<unsigned int> vec2; Παρατήρηση: Ο τύπος vector<string> είναι διαφορετικός από τον τύπο vector<unsigned int>. Δεν έχει σημασία ότι είναι και οι δύο vector< > vec1.push_back("one"); vec1.push_back("two"); vec1.push_back("three"); vec2.push_back(10); vec2.push_back(20); vec2.push_back(30); printfirstpairs(2, vec1, vec2); // Τυπώνει: 0: one, 10 1: two, 20 5

Δήλωση: template <typename T1, typename T2> class Pair T1 first; T2 second; public: Pair(const T1& firstin, const T2& secondin) : first(firstin), second(secondin) T1& getfirst() return first; T2& getsecond() return second; ; 6

Χρήση: int main() Pair<string, unsigned> p1("word1", 100), p2("word2", 200); vector< Pair<string, unsigned> > vec; vec.push_back(p1); vec.push_back(p2); vec[1].getfirst() = "word3"; cout << vec[0].getfirst() << ", " << vec[0].getsecond() << endl; cout << vec[1].getfirst() << ", " << vec[1].getsecond() << endl; 7

Όλα τα σχεδιότυπα δηλώνονται σε header files και όχι σε αρχεία υλοποίησης (.cpp,.c++), ακόμα και οι υλοποιήσεις των συναρτήσεων και κλάσεων Διαφορετικά θα έχει πρόβλημα ο linker Δηλαδή στην περίπτωση των σχεδιότυπων κλάσεων, το αρχείο κεφαλίδας περιέχει και τους ορισμούς των μεθόδων (τα κυρίως μέρη) 8

Πολλές φορές, παρότι δηλώνουμε γενικά σχεδιότυπα για κλάσεις ή συναρτήσεις, μας ενδιαφέρει να ορίσουμε διαφορετική συμπεριφορά του κώδικα για ορισμένους template τύπους Σε αυτή την περίπτωση, μπορούμε να επαναλάβουμε την υλοποίηση των συγκεκριμένων μεθόδων και συναρτήσεων, δίνοντας συγκεκριμένα ονόματα τύπων όπου χρειάζεται Για να μη δημιουργηθεί σύγκρουση κατά τη σύνδεση του κώδικα, πάντα προσδιορίζουμε το πρόθεμα inline στις υλοποιήσεις αυτές (γιατί;) 9

template <typename T> class vec2_t public: T x, y; // data member of vec2 are simple enough to // be exposed as public: no dependent data on them double length () const; // templated methods and T dot ( vec2_t<t> v ) const; // operators... static T dot (vec2_t<t> v1, vec2_t<t> v2); const vec2_t<t> operator+(const vec2_t<t> & right) const; const vec2_t<t> operator-(const vec2_t<t> & right) const;... // component-wise equal operator (global, not member): template<typename T> vec2_t<bool> operator==( const vec2_t<t> & left, const vec2_t<t> & right); 10

// Γενικευμένη υλοποίηση του τελεστή: template<typename T> vec2_t<bool> operator==( const vec2_t<t> & left, vec2_t<bool> res; res.x = left.x==right.x; res.y = left.y==right.y; return res; const vec2_t<t> & right) Όμως ο παραπάνω κώδικας θα δουλεύει καλά μόνο για ακεραίους, αφού στους αριθμούς κινητής υποδιαστολής χάνουμε ακρίβεια αναπαράστασης Παράγουμε εξειδικευμένες υλοποιήσεις γι αυτούς 11

#define COORD_EPSILON 10e-6 // specialized template implementation: inline vec2_t<bool> operator==( const vec2_t<float> & left, const vec2_t<float> & right) vec2_t<bool> res; res.x = fabs(left.x-right.x) < COORD_EPSILON; res.y = fabs(left.y-right.y) < COORD_EPSILON; return res; inline vec2_t<bool> operator==( const vec2_t<double> & left, const vec2_t<double> & right) vec2_t<bool> res; res.x = abs(left.x-right.x) < COORD_EPSILON; res.y = abs(left.y-right.y) < COORD_EPSILON; return res; 12

10 20 30 40 50 60 70 13

Node data left right Node data Node data left right left right Node Node Node Node data data data data left right left right left right left right 14

class Node const int data; Node const * const left; Node const * const right; public: ; // Διαβάζεται ανάποδα: // a const pointer to a const Node // Θα μπορούσαν και να μην είναι // const εδώ Node( const int data, const Node* const left = 0, const Node* const right = 0) : data(data), left(left), right(right) void printtree() const; 0 == NULL (C) == nullptr (C++11) Υπενθύμιση: μπορούμε να έχουμε ίδια ονόματα ορισμάτων και πεδίων. Εδώ υπονοείται: this->data(data) κλπ 15

int main() Node n4(40), n5(50), n6(60), n7(70), // φύλλα n2(20, &n4, &n5), // ενδιάμεσοι κόμβοι n3(30, &n6, &n7), // n1(10, &n2, &n3); // ρίζα n1.printtree(); 16

void Node::printTree() const cout << data << ; if(left!= nullptr) left->printtree(); if(right!= nullptr) right->printtree(); // Τυπώνει με αναζήτηση πρώτα σε βάθος (DFS). // Στο δέντρο του παραδείγματος τυπώνει: // 10 20 40 50 30 60 70 2 1 10 20 30 5 40 50 60 70 3 4 6 7 17

Με τη χρήση αναδρομής, συνεχώς μεγαλώνουμε τη stack της εφαρμογής όσο κάνουμε αναδρομικές κλήσεις με αποτέλεσμα: Να βάζουμε στον κώδικά μας το overhead της κλήσης συνάρτησης και επιστροφής από αυτή σε κάθε βήμα Να κινδυνεύουμε να προκαλέσουμε stack overflow για δένδρα μεγάλου βάθους Μπορούμε εύκολα να μετατρέψουμε τον αναδρομικό μας κώδικα σε επαναληπτικό με τη χρήση μιας στοίβας (LIFO γραμμική δομή: Last In First Out) 18

#include <stack> 1 10 void Node::printTree() const stack<const Node*> remaining; remaining.push(this); 2 20 30 5 40 50 60 70 3 4 6 7 while (!remaining.empty()) const Node * current = remaining.top(); remaining.pop(); cout << current->data << " "; if (current->right) remaining.push(current->right); if (current->left) remaining.push(current->left); 19

Τώρα, όταν επισκεπτόμαστε έναν κόμβο, στη συνέχεια επιχειρούμε να τυπώσουμε πρώτο το αριστερό παιδί του, μετά το δεξί και στο τέλος τον επόμενο κόμβο ίδιου επιπέδου (Depth-First Seearch) Αν θέλουμε να δίνουμε προτεραιότητα στους κόμβους ίδιου επιπέδου (siblings), τότε πρέπει να κάνουμε διάσχιση κατά πλάτος των επιπέδων του δένδρου (Breadth-First Search) Για τη BFS θα χρειαστούμε μια FIFO γραμμική δομή αποθήκευσης (Firtst In First Out), δηλαδή μια ουρά 20

#include <queue> 1 10 void Node::printTree() const queue<const Node*> remaining; remaining.push(this); 2 20 30 3 40 50 60 70 4 5 6 7 while (!remaining.empty()) const Node * current = remaining.front(); remaining.pop(); cout << current->data << " "; if (current->left) remaining.push(current->left); if (current->right) remaining.push(current->right); 21

template <typename T> class Node const T data; Node const * const left; Node const * const right; public: Node( const T data, const Node* const left = 0, const Node* const right = 0) : data(data), left(left), right(right) void printtree() const; ; 22

template <typename T> void Node<T>::printTree() const queue<const Node*> remaining; remaining.push(this); while (!remaining.empty()) const Node * current = remaining.front(); remaining.pop(); cout << current->data << ", " << endl; if (current->left) remaining.push(current->left); if (current->right) remaining.push(current->right); 23

Σε γενικές γραμμές, τα templates της C++ αντιστοιχούν (αλλά προϋπάρχουν) των generics της Java Τα generics υλοποιούν περίπου τη λογική των templates της C++ Η C++ επιτρέπει την εξειδίκευση μεθόδων και συναρτήσεων, χωρίς να απαιτείται η εξειδίκευση ή η παραγωγή νέας κλάσης Δεν υπάρχει στενός προσδιορισμός τύπων σε template Δεν επιτρέπεται η εξειδίκευση μεθόδων Υπάρχει η έννοια του στενότερου προσδιορισμού του generic με wildcards (<? extends Type>) 24