1 η Προαπαιτούµενη Κάθε οµάδα θα δηµιουργήσει ένα πρόγραµµα, µε πιο «πολύπλοκη» κληρονοµικότητα µε ιεραρχίες ή και πολλαπλή κληρονοµικότητα. Μπορεί να κρατήσει το πρόγραµµα που έκανε την προηγούµενη φορά και να προσθέσει παραγόµενες κλάσεις και µέλη (δεδοµένα, συναρτήσεις µέλη δοµητές κ.α.-) ή να προτείνει η οµάδα, µια νέα κλάση και τις παράγωγες κλάσεις της. (Παρακάτω προτείνονται οι γνωστές σας κλάσεις). Α1. Βασική Κλάση Χρήµατα µε 2 πεδία: ευρώ και λεπτά. Παράγωγη Κλάση Λογαριασµός µε 2 πεδία: αριθµός λογ/σµού, µέγιστο ποσό ανάληψης. Παράγωγη Κλάση Επιταγή µε 1 πεδίο: αριθµός επιταγής. Α2. Βασική Κλάση Προιόν µε 3 πεδία: όνοµα προιόντος, βάρος και τιµή Παράγωγη Κλάση Βιοµηχανικό Προιόν µε 1 πεδίο: επίπεδο επικινδυνότητας Παράγωγη Κλάση Βιολογικό Προιόν µε 1 πεδίο: είδος βιοκαλλιέργειας Α3. Βασική Κλάση Σηµείο µε 2 πεδία: συντεταγµένες x και y Παράγωγη Κλάση Σηµείο στο χώρο µε 1 πεδίο: συντεταγµένη z. Παράγωγη Κλάση Κύκλος µε ένα πεδίο: ακτίνα Α4. Βασική Κλάση Πραγµατικός µε 1 πεδίο: πραγµατικό µέρος Παράγωγη Κλάση Μιγαδικός µε 1 πεδίο: φανταστικό µέρος. Παράγωγη Κλάση Προσηµασµένος Αριθµός µε 1 πεδίο: πρόσηµο. Α5. Βασική Κλάση Χαρτί µε 2 πεδία: χρώµα, µέγεθος Παράγωγη Κλάση Κάρτα (τραπουλόχαρτο) µε 2 πεδία: αριθµός, είδος. Παράγωγη Κλάση Χαρταετός µε 1 πεδίο : σχήµα. Α6. Βασική Κλάση Ηµεροµηνία µε 3 πεδία: χρόνος, µήνας, ηµέρα. Κλάση Χρόνος µε 3 πεδία: ώρα, λεπτά, δευτερόλεπτα Παράγωγη Κλάση ραντεβού µε 1 πεδίο: ένα πίνακα από χαρακτήρες π.χ. "17/5/2010 5:32:27 ". Α7. Βασική Κλάση Άτοµο µε 4 πεδία: όνοµα, ταυτότητα, ηλικία, βάρος Παράγωγη Κλάση Υπάλληλος µε 2 πεδία: ειδικότητα, µισθός. Παράγωγη Κλάση ιευθυντής µε 1 πεδίο: τοµέα. Α8. Βασική Κλάση Υπάλληλος µε 4 πεδία: αριθµός υπαλλήλου, ηλικία, φύλο, µισθός Παράγωγη Κλάση ιευθυντής µε 1 πεδίο: όνοµα τοµέα. Παράγωγη Κλάση Μηχανικός µε 1 πεδίο: ειδικότητα. Α9. Βασική Κλάση Αποστολή µε 5 πεδία: οδός, αριθµός, πόλη, κωδικός, χώρα Παράγωγη Κλάση Γράµµα µε 2 πεδία: παραλήπτη, αποστολέα. Παράγωγη Κλάση έµα µε 1 πεδίο: µέγεθος δέµατος Α10. Βασική Κλάση Σπουδαστής µε 6 πεδία: ΑΜ, επώνυµο, όνοµα, ηλικία, τµήµα, εξάµηνο. Παράγωγη Κλάση Μεταπτυχιακός µε 1 πεδίο: όνοµα πτυχιακής. Παράγωγη Κλάση ιδάκτορας µε 2 πεδία: όνοµα διδακτορικού, έτη σπουδών. Σηµείωση: Για τα αλφαριθµητικά πεδία µπορείτε να χρησιµοποιείται και την κλάση string. BK -Προαπαιτούμενη 9 ου Εργαστηρίου - σελίs 1
2 η Προαπαιτούµενη To πρόγραµµα που δηµιουργήσατε στην 1 η προαπαιτούµενη θα τροποποιηθεί, µε σκοπό να αναδειχθεί η πολυµορφική συµπεριφορά. Για το σκοπό αυτό, θα σας χρειαστούν εικονικές και στατικές συναρτήσεις στην βασική σας κλάση. Χρησιµοποιώντας ένα πίνακα από δείκτες προς την βασική σας κλάση, προσθέστε (add) και εµφανίστε (show) αντικείµενα από τις παράγωγες κλάσεις. (Συµβουλευτείτε και το παράδειγµα 24) Point::Add() //Στατική συνάρτηση BK -Προαπαιτούμενη 9 ου Εργαστηρίου - σελίs 2
23 ΤhreeLevelHierarchy.cpp Ιεραρχία 3 επιπέδων //BK 17/05/10-23 ΤhreeLevel.cpp - Κληρονοµικότητα σε 3 επίπεδα // Point <----- Circle <-----Cylinder //Παρατήρηση: Στο παράδειγµα αυτό όλες οι µεταβλητές είναι private //και έτσι χρησιµοποιούνται µέσω των δηµόσιων συναρτήσεων get,set #include <iostream> #include <iomanip> using namespace std; class Point private: int x; // x part of coordinate pair int y; // y part of coordinate pair Point( int = 0, int = 0 ); // default constructor void setx( int ); void sety( int ); int getx() const; int gety() const; void print() const; ; // end class Point // set x in coordinate pair // set y in coordinate pair // return x from coordinate pair // return y from coordinate pair // output Point object //=================== //Class Circle inherits from class Point class Circle : public Point private: //has a private data member radius. double radius; // Circle's radius // default constructor Circle( int = 0, int = 0, double = 0.0 ); void setradius( double ); // set radius double getradius() const; // return radius double getdiameter() const; // return diameter double getcircumference() const; // return circumference double getarea() const; // return area void print() const; // output Circle object ; // end class Circle //=================== //Class Cylinder inherits from class Circle class Cylinder : public Circle private: //has a private data member height. double height; // Cylinder's height // default constructor Cylinder( int = 0, int = 0, double = 0.0, double = 0.0 ); void setheight( double ); // set Cylinder's height double getheight() const; // return Cylinder's height double getarea() const; // return Cylinder's area double getvolume() const; // return Cylinder's volume void print() const; // output Cylinder ; // end class Cylinder BK -Προαπαιτούμενη 9 ου Εργαστηρίου - σελίs 3
//=================== Point functions // point constructor Point::Point( int xvalue, int yvalue ) : x( xvalue ), y( yvalue ) // empty body void Point::setX ( int xvalue ) x = xvalue; void Point::setY( int yvalue ) y = yvalue; int Point::getX() const return x; int Point::getY() const return y; void Point::print() const cout << '[' << getx() << ", " << gety() << ']'; //=================== Circle functions // circle constructor Circle::Circle( int xvalue, int yvalue, double radiusvalue ) : Point( xvalue, yvalue ) // call base-class constructor setradius( radiusvalue ); void Circle::setRadius( double radiusvalue ) radius = ( radiusvalue < 0.0? 0.0 : radiusvalue ); double Circle::getRadius() const return radius; double Circle::getDiameter() const return 2 * getradius(); double Circle::getCircumference()const return 3.14159 * getdiameter(); double Circle::getArea() const return 3.14159 * getradius() * getradius(); void Circle::print() const cout << "Center = "; Point::print(); // invoke Point's print function cout << "; Radius = " << getradius(); //=================== Cylinder functions // Cylinder constructor Cylinder::Cylinder( int xvalue, int yvalue, double radiusvalue, double heightvalue ) : Circle( xvalue, yvalue, radiusvalue ) //κλήση δοµητή κύκλου setheight( heightvalue ); void Cylinder::setHeight( double heightvalue ) height = ( heightvalue < 0.0? 0.0 : heightvalue ); double Cylinder::getHeight() const return height; // redefine Circle function getarea to calculate Cylinder area double Cylinder::getArea() const return 2 * Circle::getArea() + getcircumference() * getheight(); double Cylinder::getVolume() const return Circle::getArea() * getheight(); void Cylinder::print() const Circle::print(); cout << "; Height = " << getheight(); BK -Προαπαιτούμενη 9 ου Εργαστηρίου - σελίs 4
//=================== main int main(int argc, char *argv[]) // instantiate Cylinder object Cylinder cylinder( 12, 23, 2.5, 5.7 ); // display point coordinates cout << "X coordinate is " << cylinder.getx() << "\ny coordinate is " << cylinder.gety() << "\nradius is " << cylinder.getradius() << "\nheight is " << cylinder.getheight(); cylinder.setx( 2 ); // set new x-coordinate cylinder.sety( 2 ); // set new y-coordinate cylinder.setradius( 4.25 ); // set new radius cylinder.setheight( 10 ); // set new height // display new cylinder value cout << "\n\nthe new location and radius of circle are\n"; cylinder.print(); // display floating-point values with 2 digits of precision cout << fixed << setprecision( 2 ); // display cylinder's diameter cout << "\n\ndiameter is " << cylinder.getdiameter(); // display cylinder's circumference cout << "\ncircumference is " << cylinder.getcircumference(); // display cylinder's area cout << "\narea is " << cylinder.getarea(); // display cylinder's volume cout << "\nvolume is " << cylinder.getvolume(); cout << endl; system("pause"); return EXIT_SUCCESS; BK -Προαπαιτούμενη 9 ου Εργαστηρίου - σελίs 5
24 Polymorph.cpp Πολυµορφισµός //BK 17/05/10 24 Polymorph.cpp - Πολυµορφισµός // Point <----- Circle <-----Cylinder //Παρατήρηση: Στο παράδειγµα αυτό, protected οι µεταβλητές, στις γονικές κλάσεις. //Περιέχει πίνακα P[maxn] από δείκτες προς αντικείµενα point. #include <iostream> #include <iomanip> #include <fstream> #include <typeinfo> //for typeid using namespace std; class Point protected: int x; // x part of coordinate pair int y; // y part of coordinate pair static int n; //στατικός αριθµός των σηµείων Point( int = 0, int = 0 ); virtual void print() const; virtual void givedata () ; //Εικονικές συναρτήσεις static void add(); //Στατικές συναρτήσεις static void show(); static void write(); static void read(); static int getn() ; int getshape(); //return 1 (κύκλος) ή 2 (κύλινδρος) ; // end class Point //=================== int Point::n =0 ; //Αριθµός που µετράει όλα τα αντικείµενα (σηµεία) const int maxn = 3; //Mέγιστο µέγεθος Πίνακα Point* P[maxn]; //Πίνακας δεικτών προς ΣΗΜΕΙΑ (βασική κλάση) //=================== //Class Circle inherits from class Point class Circle : public Point protected: double radius; // Circle's radius // default constructor Circle( int = 0, int = 0, double = 0.0 ); virtual void print() const; virtual void givedata () ; ; // end class Circle //=================== BK -Προαπαιτούμενη 9 ου Εργαστηρίου - σελίs 6
//Class Cylinder inherits from class Circle class Cylinder : public Circle protected: double height; // Cylinder's height // default constructor Cylinder( int = 0, int = 0, double = 0.0, double = 0.0 ); double getarea() const; double getvolume() const; void print() const; void givedata () ; ; // end class Cylinder //=================== Point FUNCTIONS // point constructor Point::Point( int xvalue, int yvalue ) : x( xvalue ), y( yvalue ) int Point::getn()//στατική return n; void Point::print() const //εικονική cout << '[' << x << ", " << y << ']'; void Point::show() //στατική for (int i=0;i<n;i++) P[i]->print(); //Tυπώνει ανάλογα το αντικείµενο (κύκλο / κύλινδρο). cout << endl; void Point::giveData() //εικονική cout << "X:"; cin >> x; cout << "Y:"; cin >> y; void Point::add() //στατική char choice='1' ; while ( true ) cout <<" \ngiving data... \n1: KYKLOS\n2: KYLINDROS\n0: Stop \nyour choice:=> "; cin >> choice; if (choice == '0') break ; BK -Προαπαιτούμενη 9 ου Εργαστηρίου - σελίs 7
//ΕΠΙΛΟΓΗ ΗΜΙΟΥΡΓΙΑΣ ΑΝΤΙΚΕΙΜΕΝΟΥ (στον πίνακα P) if ( choice == '1') P[n]=new Circle; else if ( choice == '2') P[n]=new Cylinder; else cout << "Dose mono 1 (Kyklos) kai 2 (Kylinder)\n\n"; continue; P[n++]-> givedata(); // εδοµένα είτε για κύκλο είτε για κύλινδρο if (n == maxn) cout << "Pinakas full!!\n" ; break; int Point::getShape() //γυρνάει ακέραιο 1,2 if ( typeid (*this) == typeid(circle) ) //typeid operator to find the class return 1; else if ( typeid(*this) == typeid(cylinder) ) return 2; else cerr << "\nwe have 2 types of shapes"; exit(1); void Point::write() //στατική int size; //το µέγεθος κάθε αντικειµένου (µπορεί να διαφέρει) //π.χ. ο κύλινδρος έχει επι πλέον µια µεταβλητή το ύψος int shape; //0 ή 1 ofstream fo; fo.open("shapes.txt", ios::binary ios::app); if(!fo) cout << "\ncan't open file\n"; return; for(int i = 0; i < n; i++) shape=p[i]->getshape(); //τι αντικείµενο είναι(κύκλος ή κύλινδρος?). fo.write ( (char*) &shape, sizeof(shape)); //εγγραφή shape (1 ή 2) if (shape==1) size = sizeof(circle); else size = sizeof(cylinder); fo.write( (char*) P[i], size); //εγγραφή στο αρχείο του αντικειµένου if(!fo) cout << "\ncan't write to file\n"; return; fo.close(); //end of write void Point::read() //στατική int size; int shape; ifstream fi; fi.open("shapes.txt", ios::binary); BK -Προαπαιτούμενη 9 ου Εργαστηρίου - σελίs 8
if(!fi) cout << "\ncan't open file\n"; return; n = 0; // µηδενίζονται όλα τα αντικείµενα // και δηµιουργούνται νέα από το αρχείο while(true) //διαβάζει το shape (1 ή 2) fi.read ( (char*)&shape, sizeof(shape) ); if( fi.eof()) break; if(!fi) cout << "\ncan't read type from file\n"; return; if ( shape==1) P[n] = new Circle; size = sizeof(circle); else P[n] = new Cylinder; size = sizeof(cylinder); //διαβάζει το αντικείµενο στο οποίο θα δείχνει ο ptr P[n] fi.read((char*) (P[n]), size); cout << endl; if(!fi) cout << "\ncan't read data from file\n"; return; if (n < maxn+1 ) //να διαβάζει έως το max µέγεθος του πίνακα n++; else break; cout << "\nread APO TO ARXEIO " << n << " SHAPES\n"; fi.close(); //end of read //=================== Circle FUNCTIONS // circle constructor Circle::Circle( int xvalue, int yvalue, double radiusvalue ) : Point( xvalue, yvalue ) radius = radiusvalue; void Circle::print() const cout << "Center = "; Point::print(); // invoke Point's (virtual) print function cout << "; Radius = " << radius; void Circle::giveData () Point::giveData(); // invoke Point's (virtual) givedata function cout << "; Radius = " ; cin >>radius ; // radius> 0.0 BK -Προαπαιτούμενη 9 ου Εργαστηρίου - σελίs 9
//=================== Cylinder FUNCTIONS // Cylinder constructor Cylinder::Cylinder( int xvalue, int yvalue, double radiusvalue, double heightvalue ) : Circle( xvalue, yvalue, radiusvalue ) //καλείται ο δοµητής του κύκλου height = heightvalue ; void Cylinder::print() const Circle::print(); // invoke Circle's (virtual) print function cout << "; Height = " << height; void Cylinder::giveData () Circle::giveData(); // invoke Circle's (virtual) givedata function cout << "; Height = " ; // > 0.0 cin >> height ; //=================== main int main(int argc, char *argv[]) //θα µπορούσε να υπάρχει µενού για τις παρακάτω εντολές cout << "\n\nadd\n\n"; Point::add(); cout << "\n\nshow\n\n"; cout << "There are " << Point::getn() << " objects to show\n"; Point::show(); cout << "\n\nwrite TO FILE\n\n"; cout << "There are " << Point::getn() << " objects to write\n"; Point::write(); cout << "\n\nread FROM FILE\n\n"; Point::read(); Point::show(); cout << endl; system("pause"); return EXIT_SUCCESS; BK -Προαπαιτούμενη 9 ου Εργαστηρίου - σελίs 10