Object Oriented Programming [Τα Βασικα]

...το μέρος για να ξεκινήσετε!

Συντονιστής: adem1

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

Σημαντικό είναι να χρησιμοποιήσετε την υπηρεσία http://imagebin.ubuntu-gr.org για τις εικόνες.

Object Oriented Programming [Τα Βασικα]

Δημοσίευσηαπό BlackSlash13 » 15 Αύγ 2008, 13:23

Γραμμένο απο εμένα. Οι κώδικες εχουν γινει compile με g++ . Καλή ανάγνωση.


Α ν τ ι κ ε ι μ ε ν ο σ τ ρ ε φ η ς ##
################## π ρ ο γ ρ α μ μ α τ ι σ μ ο ς ##
#################################### σ ε γ λ ω σ σ α C + + ##
##

Καποια βασικά για να πιάσετε την ιδέα:
κλασσική αναλογία για να κατανοήσετε τον OOp είναι αυτή με το αμάξι.
Υποθέστε λοιπόν ότι οδηγάτε το αυτοκίνητο σας και θέλετε να πάτε πιο γρήγορα. Γι αυτό πατάτε περισσότερο το
γκάζι. Τόσο απλό.

Τι πρέπει να προηγηθεί όμως πριν μπορέσετε να το κάνετε αυτό ;

1) Πρέπει να κατασκευαστεί το αυτοκίνητο.
2) Για να κατασκευαστεί το αυτοκίνητο πρέπει να υπάρχουν μηχανολογικά σχέδια αυτού.
3) Αυτά τα σχέδια, περιλαμβάνουν τα σχέδια για το γκάζι, το φρένο, το τιμόνι κλπ κλπ.

Κατά μία έννοια λοιπόν, το πετάλι για το γκάζι/φρενο κλπ, στην ουσία "κρύβει" τον μηχανισμό της επιτάχυνσης
του αυτοκινήτου. Ετσι, όλος ο κόσμος ξέρει να οδηγάει πολύ εύκολα, χωρίς να γνωρίζει πως λειτουργεί ένα
αυτοκίνητο.

Αυτός ο μηχανισμός γίνεται μέσω μιας function. Η function περιέχει όλα αυτά τα σχέδια της επιτάχυνσης ώστε oταν πατάμε το πετάλι του γκάζι, το αυτοκίνητο να επιταχύνει. Υπάρχει επίσης μια άλλη function, η οποία περιέχει τον μηχανισμό για να σταματάει το αμάξι όταν πετάμε φρένο. Ακόμα, υπάρχει κι άλλη function που περιέχει τον μηχανισμό για να στρίβουμε το αμάξι με το τιμόνι. Όλες αυτές οι functions περιέχουν του μηχανισμούς για λειτουργίες του αυτοκινήτου.

Τον οδηγό όμως, δεν τον ενδιαφέρει ο μηχανισμός αλλά η λειτουργία της function (δηλαδή να γκαζώνει, να φρενάρει και στρίβει).

Class, λοιπόν, είναι μια συλλογή - ένα σπίτι - που στεγάζει αυτές τις functions, σαν το σπίτι του μηχανικου που έχει στο γραφείο του
τα σχέδια του νέου μοντέλου αμαξιού της εταιρίας. Σε μία class μπορείς να έχεις μέσα της, 1 ή και περισσότερες member function. Όλες τους
όμως, όπως είπαμε, θα περιέχουν μηχανισμούς που αφορούν λειτουργίες της Class. Όπως τα σχέδια του μηχανικού (σχεδιο για το γκαζι, σχέδιο για το φρενο κλπ) λειτουργίες του αυτοκινήτου.
Όμως δεν μπορούμε να οδηγήσουμε τα σχέδια. Δεν μπορούμε να πατήσουμε το γκάζι πάνω στην κόλα Α2 που σχεδιάσαμε το γκάζι και να πάρει κινηθεί
το αυτοκίνητο στη ζωγραφιά-σχέδιο. Πρέπει λοιπόν, κάποιος, να κατασκευάσει ένα πραγματικό αυτοκίνητο. Να περάσει από το χαρτί στην
πραγματικότητα της ζωής μας. Έτσι, λοιπόν, αφού έχουμε τα μηχανολογικά σχέδια (δηλαδή την Class), φτιάχνουμε ένα αυτοκίνητο
(δηλαδή ένα Object της Class). Φυσικά μπορούμε να φτιάξουμε 1 και περισσότερα αυτοκίνητα από ένα σχέδιο - άρα μπορούμε να φτιάξουμε ένα ή
και περισσότερα Objects από μια Class. Η Class - δηλαδή τα μηχανολογικά σχέδια του αυτοκινήτου - περιέχουν τους μηχανισμούς
(member functions) οι οποίεις θα υλοποιηθούν με την σειρά τους στο αυτοκίνητο που θα κατασκευάσουμε (δηλαδή το Object).Όταν
πατάτε το γκάζι, τότε στην ουσία καλείται μία λειτουργία του αυτοκινήτου : την επιτάχυνση. Ανάλογα, στην C++, στέλνετε μυνήματα στο
Object (αυτοκίνητο)για να επιταχύνει. Αυτή η διαδικασία της "κλήσης" ενός μηχανισμού/ μιας λειτουργίας(member function) της
Class(μηχανολογικα σχέδια αυτοκινήτου) για να υλοποιηθεί από το Object(αυτοκίνητο) λέται member-function call ή αλλιώς Object Service Request. Κάθε
αυτοκίνητο όμως, έχει το δικό του χρώμα, το δικό το σαλόνι, το δικό του max ταχύτητας, ξεχωριστή δεξαμενή καυσιμων κλπ. Μπορεί να είναι
αυτοκίνητο που προέρχεται από το ίδιο μηχανολογικό σχέδιο. Toyota Auris θα βρείς σε πολλά μοντέλα. Όλα όμως προέρχονται από το ίδιο
σχέδιο. Είναι απλώς διαφορετικά μοντέλα. Σε τι διαφέρουν δηλαδή ; Στις ιδιότητες (attributes). Αρα κάθε object που μπορεί να προέρχεται από
μια Class μπορεί να διαφοροποιείται από ένα Object που προέρχεται από την ίδια Class, γιατί θα έχει διαφορετικά attributes (πχ διαφορετικό
χρωμα). Προσέξτε όμως, οι ιδιότητες (attributes) ΔΕΝ ΕΙΝΑΙ μέρος του μηχανολογικού σχεδιού (δηλαδή της Class) αλλά είναι μέρος που
στεγάζεται στο Object καθ' αυτό. Εν ολίγης, function (member function) : Ο μηχανισμός που υλοποιεί τις διάφορες λειτουργίες
ενός προγράμματος. Το "πώς" της υλοποιεί, παραμένει "κρυφό" μέσα στην function και δεν σας ενδιαφέρει. Class είναι μια συλλογή απο
πληροφορίες - λειτουργίες - μηχανισμούς, που "κρύβονται" μέσα στις member functions (δηλαδή functions που είναι μέλη της Class). Object
είναι αντίτυπο (instance) - υλοποίηση της Class. πχ ενα αυτοκίνητο που έχει μονο γκάζι. πχ ένα αλλό που έχει και γκαζι και φρένο. Attributes είναι οι ιδιότητες του κάθε αντικειμένου ξεχωριστά (πχ το χρώμα του).

## 0x01 --Classes ##
#############
Είναι μία συλλογή από ιδιότητες. Φανταστείτε κάτι σαν τα σχέδια ενός μηχανικού.
Απλά να ξέρετε ότι είναι μία συλλογή από ιδιότητες, τίποτα παραπάνω για την ώρα.
Εύκολος ορισμός ε ;

Κάθε class έχει 2 πράγματα: Μεταβλητές και Συναρτήσεις (Variables & Functions)

Οι variables(μεταβλητές) που βρίσκονται μέσα σε μία class έχουν ένα ειδικό όνομα.
Λέγονται: Member Variables ή Data Members.

Οι Συναρτήσεις( functions) που βρίσκονται μέσα σε μία class έχουν κι αυτές ένα ειδικό όνομα
Λέγονται: Member Functions ή Methods.
############################################################

Παράδειγμα: πχ έστω ότι έχουμε μια class Gatoula()
Αυτή πιθανόν να περιέχει τα εξής:
Member Variables: int ilikia, char xroma, char ratsa, char xroma_mation, klp klp
Member Functions: void Niaourisma(), void Upnos(), void Perpatima() , void Kunigi_Pontikion() klp klp



Παράδειγμα μιας class ακολλουθεί ακριβως παρακάτω ::::
Κώδικας: Επιλογή όλων
                        
                                                                  
class Gatoula                                                            
{                                                                  
      unsigned int IlikiaTis;                                                      
      unsigned int VarosTis;                                                   
      void Niaou();                                                         
};




##
## 0x02 --Ονοματολογία και στιλ ##
######################
Κάθε προγραμματιστής έχει υιοθετήσει ένα δικό του coding style. Ετσι και εδώ θα πρέπει να
κατασταλάξετε στην ονομασία των Data Members και των Functions. Διαλέξτε ένα στιλ:

[1] . itsAge
[2] . myAge
[3] . m_Age (το m από την λέξη member)
[4] . mAge





##
## 0x03 --Object ##
#############
Εχοντας ήδη φτιάξει μια Class με το ονομα Gatoula, τώρα θα φτιάξουμε μία πραγματική γάτα.
Παράδειγμα δήλωσης αντικειμένου

Κώδικας: Επιλογή όλων
Gatoula Lucifer    //defines an object Lucifer      



###############################################################

O Lucifer είναι πλέον ένα αντικείμενο τύπου Gatoula, δηλαδή, περιέχει όλες τις ιδιότητες
(μην ξεχνας ότι η class είναι μία συλλογή πληροφοριών) της Class που προέρχεται.
μπορεί να νιαουρίσει, πχ Lucifer.Niaou();
δώστου μια ηλικία, πχ Lucifer.IlikiaTis = 5;

###############################################################

Όταν φτιάχνεις μια class σκέψου ότι φτιάχνεις τον κόσμο. Για να φτιάξεις μία γάτα στο πρόγραμμα σου
πρέπει να τις δώσεις τα χαρακτηριστικά που έχει στον πραγματικό κόσμο. Δηλαδή να της δώσεις
όνομα, χρώμα, ράτσα, πόδια, ουρά, μάτια, μύτι, αυτιά κλπ . Μετά να τις δώσεις αυτά που μπορεί να κάνει
δηλαδή να περπατάει, να κοιμαται, να τρώει, να νιαουρίζει, να κυνηγάει ποντίκια, να πηδάει ψηλά
να εχει 7 ζωές (λεμε τώρα) κλπ. Η class είναι οι οδηγίες για να φτιάξεις πολλές γάτες στ ο προγραμμα
σου. Οι οντότητες που θα πάρουν σάρκα και οστά μέσω των οδηγιών της class είναι το αντικείμενο.
Το αντικείμενο χρησιμοποιεί τις ιδιότητες και τα χαρακτηριστικά μιας class. Οπότε μπορείς να φτιάξεις
διάφορα αντικείμενα/διάφορες γάτες δίνοντας τιμές στις ιδιοτήτες μιας Class. Πχ ο ένας γάτος θα
έχει ηλικία 3, ο άλλος 4, και ο άλλος 3. Αλλά ο τελευταίος θα έχει μαύρο χρώμα, ενώ ο πρώτος θα έχει
καφέ. Επίσης ο μεσαίος γάτος θα μπορεί να κυνηγάει ποντίκια, αλλό οι άλλοι δύο όχι. Όλα αυτά έχουν να
να κάνουν με μία class που έχεις ορίσει την γάτα στο πρόγραμμα σου. Στα αντικείμενα αυτής, δίνεις
τις ιδιότητες της





## 0x04 --Public & Private members
########################


Εξορισμού, όλα τα members της class είναι private.

Ας δούμε ένα παράδειγμα με public :

Κώδικας: Επιλογή όλων
/* Example
#include <iostream>
using namespace std;

class Cat      // Defining Class me to onoma Cat
{
   public:   // public access
      int myAge;              //member var
      int myWeight;   //member var
};   // <--------- min ksexaseis to erotimatiko sto telos tis Class

int main()
{
   Cat Kastrato;      define a Object of the Class
   Kastrato.myAge = 5;   // O Kastrato einai pleon 5 xronon
   cout << "O Kastrato einai " << Kastrato.myAge << " xronon" << endl;
   return 0;
}


#####################################################################

## Αν αφαιρέσω την λέξη public, τότε δεν μπορώ μες την main να γράψω Kastrato.myAge = 5;


Ας δούμε ένα παράδειγμα με Private (πιο ασφαλές).

Για να αλλάξω τιμή στα private members θα πρέπει να φτιάξω public methods που να έχουν
πρόσβαση σε αυτά. Αυτές τις ονομάζουμε accessors (access = πρόσβαση)



Κώδικας: Επιλογή όλων
                                                                        

#include <iostream>
using namespace std;

class Cat
{
   public:
      int GetAge() const { return myAge; }   // accessor function inline
      void SetAge( int age) { myAge = age; }   // accessor function inline
      void Niaou();      // public method
   private:
      int myAge;      // private data member;
};

int main()
{
   Cat Arpiah;
   Arpiah.SetAge(5);
   cout << "I Ilikia tis Arpiah einai : " << Arpiah.GetAge() << endl;
   return 0;
}





##
## 0x05 --Constructor / Destructor ##
########################

Κάθε αντικείμενο έχει εναν Constructor και εναν Destructor (υπάρχει και ο Copy Constructor αλλα δεν θα σχολιασω τιποτα γι δ'αυτον).
Αυτά είναι κάτι σαν την προεπιλεγμένη τιμή που παίρνει το αντικείμενο με το που δημιουργείται. Ειναι τι θελουμε να γινετε οταν δημιουργειται και οταν καταστρέφεται.
πχ Εστω οτι θέλουμε εξορισμού, ο γάτος μας να είναι 9 χρονών με το που τον αρχικοποιουμε:


Κώδικας: Επιλογή όλων
#include <iostream>
using namespace std;

class Gatos
{
   public:
      Gatos ( int arxiki_ilikia) { myAge = arxiki_ilikia; }      // Constructor; i allios Gatos() { myAge = 9 ; } i allios Gato(): myAge(9) {}
      ~Gatos() {}      // Destructor - den kanei tipota
      int getAge() const { return myAge; }   // accessor function
      int setAge( int age ) { myAge = age ; }   // accessor function
   private:
      int myAge;
};

int main()
{
   Gatos Garfield(9);
   cout << "O Garfield einai " << Garfield.getAge() << " xronon " << endl;
   Garfield.setAge(5);
   cout << "Tora omos einai : " << Garfield.getAge() << " xronon " << endl;
   return 0;
}



##
## 0x06 --Inheritance ##
###############
Εχουμε τα θηλαστικα[b]. Αυτα κοιμουνται και τρωνε. Ο Σκυλος ειναι [b]θηλαστικο. Ο Σκυλος γαβγιζει.
[Ο Σκυλος ειναι θηλαστικο. Ο Σκυλος τρωει, κοιμαται και γαβιζει. Το πιασες ;
Ορισμός --->
Class DerivedClass : accessType BasedClass


Παράδειγμα:
Κώδικας: Επιλογή όλων
                                 
                                                                  
#include <iostream>
using namespace std;

class Thilastiko
{
   public:
      Thilastiko(): itsAge(0) {}
      ~Thilastiko() {}
      int GetAge() const { return itsAge; }
      void SetAge(int age) { itsAge = age; }
      void Sleep()  const { cout << "Shhhh. I am sleeping\n"; }
   protected:
      int itsAge;
};

class Skylos : public Thilastiko
{
   public:
      void Bark() const { cout << "Gav Gav Gav!!!\n"; }
};

int main()
{
   Skylos Rudolf;
   cout << "O Rudolf einai : " << Rudolf.GetAge() << " xronon " << endl;
   Rudolf.SetAge(3);
   cout << "O Rudolf einai : " << Rudolf.GetAge() << " xronon " << endl;
   Rudolf.Bark();
   return 0;
}




Overloading Constructors
Παράδειγμα

Κώδικας: Επιλογή όλων
#include <iostream>
using namespace std;

class HeavyMetalBand
{
   public:
      HeavyMetalBand(){} // Constructor
      HeavyMetalBand( int members ):itsMembers(members) {}  // i allios meta to (int members) { itsMembers = members; }
      ~HeavyMetalBand() {}   // Destructor

      // Accessors
      int GetMembers() const { return itsMembers; }
      void SetMembers( int mMembers ) { itsMembers = mMembers; }
   
      // Other Methods
      void PlayMusic() const { cout << "...Keep on rocking in the free world...\n"; }

   protected:
      int itsMembers;
};

class LeadGuitar : public HeavyMetalBand
{
   public:
      // Constructors & Overloaded Constructors
      LeadGuitar() {}
      LeadGuitar(int yearsOfExperience ) { itsYearsExp = yearsOfExperience;} // A Tropos me =
      LeadGuitar(int yearsOfExperience, int Age):itsYearsExp(yearsOfExperience), itsAge(Age) {} // B Tropos me :
      LeadGuitar(int Age, int Guitars, int SongsComposed):itsAge(Age), itsGuitars(Guitars), itsSongs(SongsComposed) {}
      ~LeadGuitar() {}

      //Accessors
      int GetExp() const { return itsYearsExp; }
      int GetAge() const { return itsAge; }
      int GetNumOfGuitars() const { return itsGuitars; }
      int HowManySongs() const { return itsSongs; }

      void SetExp( int mYears ) {itsYearsExp = mYears;}   // Den yparxei o B Tropos
      void SetAge( int mAge ) { itsAge = mAge; }      // kathos edo exoume Methods (Member Function)
      void SetGuitars ( int mGuitars ) { itsGuitars = mGuitars; }   // kai oxi  constructors kai destructors
      void SetSongs( int mSongs) { itsSongs = mSongs; }   // o A Tropos paizei mono me Constructors kai Destructors

      // Other Methods
      void RiffEmAll() const { cout << "Metal up your ass! Treat me, baby ... \n"; }

   private:
      int itsYearsExp, itsAge, itsGuitars, itsSongs;
};

int main()
{
   HeavyMetalBand Metallica(4);
   cout << "Metallica is consisted of " << Metallica.GetMembers() << " members " << endl;   
   
   LeadGuitar KirkHammet;
   LeadGuitar DaveMustaine(17,32);
   LeadGuitar JamesHetfield(17,11,52);   //He is Rythm Guitar anyway...
   // cout whatever ... I am boring 4 typing so long... You got the point, don't ya ?
   return 0;
}


#####################################################################

Overriding & Hiding & Calling Base Methods

Overriding:
Εχω μια method στην base class Thilastiki με το ονομα Speak() { cout << "To thilastiko milaei" }
και μετα φτιαχνω μια derived class Skylos και θελω να βαλω κι εδω μια method Speak()
υπάρχει όμως ήδη απο πριν αλλα εγω θελω ο σκυλος να κανει Γαβ Γαβ και οχι να λεει: "Το θηλαστικο μιλάει"
ετσι φτιαχνω μια ίδια method, με
[1] --> Ιδιο ή διαφορετικο return type
[2] --> Ιδιο όνομα
[3] --> Ιδια λίστα παραμέτρων
[4] --> Με την λέξη const (αν έγινε η χρηση της στην base class method)
[5] --> Με διαφορετικό implementation ( πχ cout << cout << "Gav Gav Gav" )

#####################################################################

Παράδειγμα: Overriding

Κώδικας: Επιλογή όλων
class Mammal
{
  public:
    // constructors
    Mammal() {}
    ~Mammal() {}
    //Other methods
    void Speak()const { cout << ?Mammal sound!\n?; }
    void Sleep()const { cout << ?shhh. I’m sleeping.\n?; }
};

class Dog : public Mammal
{
  public:
   // Constructors
    Dog(){}
    ~Dog(){}
    // Other methods
    void WagTail() const { cout << ?Tail wagging...\n?; }
    void BegForFood() const { cout << ?Begging for food...\n?; }
    void Speak() const { cout << ?Woof!\n?; }   // Overriding Base Method Speak
};




Hiding:
Αν η base class method Speak έχει διάφορες παραλαγες τις (δηλαδη έχει γίνει overload) πχ Speak(Greek),
ή Speak(int lekseis, int protaseis) και φυσικά υπάρχει και η απλή η Speak(), τότε:
αν κάνω overriding την Speak() , τότε αυτόματα, κρύβω τις παραλαγές τις δεν μπορώ να τις καλέσω από την
derived class.

Παράδειγμα: Hiding ##

Κώδικας: Επιλογή όλων
class Mammal
{
   public:
   Mammal(){}
   ~Mammal(){}
   void Speak() const { cout << "To thilastiko milise kai eipe tin teleutaia tou leksi" ; }
   void Speak(int words) { cout << "To thilastiko milise kai eipe tis " << words << " teleutaies tou lekseis"; }
};

class Dog: public Mammal
{
   public:
   Dog() {}
   ~Dog() {}
   void Speak() const { cout << "O skylos milise kai eipe tin teleutaia tou leksi"; }
};

int main
{
   Mammal Platupodaros;
   Dog Skylaki;
   Platupodaros.Speak();
   Sylaki.Speak()
   Platupodaros.Speak(5);
   // Skylaki.Speak(5) ----> Θα ειναι ερρορ γιατι έχει γινει hidden



To πιάσατε ; Οποτε υπάρχει ο κανόνας:

Αν κανεις override μια method που εχει γινει overload , τοτε εχει 2 επιλογες:
[1] --> Θα κανει override αυτη που θες και αυτοματα η αλλες θα γινουν hidden
[2] --> Θα τις κανεις ολες αναγκαστικα overriding χωρις να μεινει καμια hidden



Κώδικας: Επιλογή όλων
#include <iostream>
using namespace std;
class Mammal
{
   public:
   Mammal(){}
   ~Mammal(){}
   void Speak() const { cout << "To thilastiko milise kai eipe tin teleutaia tou leksi\n" ; }
   void Speak(int words) { cout << "To thilastiko milise kai eipe tis " << words << " teleutaies tou lekseis\n"; }
};

class Dog: public Mammal
{
   public:
   Dog() {}
   ~Dog() {}
   void Speak() const { cout << "O skylos milise kai eipe tin teleutaia tou leksi\n"; }

int main()
{
   Mammal Platupodaros;
   Dog Skylaki;
   Platupodaros.Speak();
   Skylaki.Speak();
   Platupodaros.Speak(5);
   Skylaki.Mammal::Speak(5); // Ayto paizei mia xara omos! Xexexexe!
   // Skylaki.Speak(5) ----> Θα ειναι ερρορ γιατι έχει γινει hidden
   return 0;
}




Κώδικας: Επιλογή όλων
#include <iostream>
using namespace std;
class Mammal
{
   public:
   Mammal(){}
   ~Mammal(){}
   void Speak() const { cout << "To thilastiko milise kai eipe tin teleutaia tou leksi\n" ; }
   void Speak(int words) { cout << "To thilastiko milise kai eipe tis " << words << " teleutaies tou lekseis\n"; }
};

class Dog: public Mammal
{
   public:
   Dog() {}
   ~Dog() {}
   void Speak() const { cout << "O skylos milise kai eipe tin teleutaia tou leksi\n"; }

int main()
{
   Mammal Platupodaros;
   Dog Skylaki;
   Platupodaros.Speak();
   Skylaki.Speak();
   Platupodaros.Speak(5);
   Skylaki.Mammal::Speak(5); // Ayto paizei mia xara omos! Xexexexe!
   // Skylaki.Speak(5) ----> Θα ειναι ερρορ γιατι έχει γινει hidden
   return 0;
}





Bypass the Hiding
Τι γίνετε όμως βαριέστε να κάνετε overriding όλες τις methods (καλό είναι να μην βαριέστε όμως) ;
Πώς θα χρησιμοποιήσετε την method Speak(int words) στο Skylaki ; ; ;
#######################################################################
## Παράδειγμα: bypass the hiding

Κώδικας: Επιλογή όλων
#include <iostream>
using namespace std;
class Mammal
{
   public:
   Mammal(){}
   ~Mammal(){}
   void Speak() const { cout << "To thilastiko milise kai eipe tin teleutaia tou leksi\n" ; }
   void Speak(int words) { cout << "To thilastiko milise kai eipe tis " << words << " teleutaies tou lekseis\n"; }
};

class Dog: public Mammal
{
   public:
   Dog() {}
   ~Dog() {}
   void Speak() const { cout << "O skylos milise kai eipe tin teleutaia tou leksi\n"; }

int main()
{
   Mammal Platupodaros;
   Dog Skylaki;
   Platupodaros.Speak();
   Skylaki.Speak();
   Platupodaros.Speak(5);
   Skylaki.Mammal::Speak(5); // Ayto paizei mia xara omos! Xexexexe!
   // Skylaki.Speak(5) ----> Θα ειναι ερρορ γιατι έχει γινει hidden
   return 0;
}


########################################################################
##
## Το παραπάνω κόλπο είναι : derived_class.base_class::base_method(parameter)
## Προσοχή όταν κάνετε overriding να μην ξεχνάτε την λέξη const αν υπάρχει [\b]
##########################################################################


[b]Virtual Methods (How deep is the rabbit's hole)

Ξέρουμε ότι ο Σκύλος κληρονομεί τις ιδιότητες (data & methods) των θηλαστικών. Λογικό και κατανοητό.
Η C++ όμως παρέχει και το εξής: pointer τύπου δεδομένων base class που κρατάει ως τιμή την διεύθυνση μνήμης
της derived class. Δηλαδή pointer τύπου Θηλαστικού, που κρατάει την διεύθυνση του Σκύλου. Τωρα θα πείτε: Ε (;;;;)
Δηλαδή:

Thilastiko *ptr = new Skylos // ενώ μέχρι τώρα γράφαμε : Skylos ptr;


Τι κάνει ^^^ : Φτιάχνει ένα αντικείμενο Skylos, και έναν pointer που δέχεται τιμές τύπου Thilastiko.
Ο Σκύλος όμως είναι θηλαστικό, άρα είμαστε μια χαρά! (αφού class Skylos : public Thilastiko )
Αλλάζει επίσης και ο τρόπος που καλούμε methods.
Παλιά (που λεει ο λογος) :
ptr.method();

Τώρα :
ptr -> method();


Πιο είναι το πρόβλημα όμως ; Αν κάνεις overriding μια method, τότε αντί να καλέσει την method απο την derived class
θα καλέσει την hidden method της base class. Δες το ακόλουθω παράδειγμα:

##Example - Παλιος Τρόπος############################################################

Κώδικας: Επιλογή όλων
                              
                                                                                 
#include <iostream>
using namespace std;

class Thilastiko
{
   public:
      void Speak() { cout << "Thilastiko milaei" << endl; }
};

class Skylos : public Thilastiko
{
   public:
      void Speak()   { cout << "Woof Woof Woof" << endl;}
};

int main()
{
   Skylos Beetoven;
   Beetoven.Speak();
   return 0;
}



###########################################################################
## Output: Woof Woof Woof
###########################################################################


Κώδικας: Επιλογή όλων
Example - Καινούριος Τρόπος (δες την διαφορα στο output)                                             

#include <iostream>
using namespace std;

class Thilastiko
{
   public:
      void Speak() const { cout << "Thilastiko milaei" << endl; }
};

class Skylos : public Thilastiko
{
   public:
      void Speak() const { cout << "Woof Woof Woof" << endl;}
};

int main()
{
   
   Thilastiko *Beetoven = new Skylos;
   Beetoven -> Speak();   // palia grafame Beetoven.Speak();
   
   return 0;
}


##########################################################################
## Output: Thilastiko milaei
###########################################################################



Όπως βλέπεις δεν πιάνει το overriding. Αυτό συμβαίνει γιατί ο pointer επειδή είναι τύπου Thilastiko βλέπει όλες τις function
του thilastiko (aka της base class) . Ο τρόπος για να χρησιμοποιήσεις το overriding όπως και πριν είναι ένας:

Να κάνεις την method speak, τύπου virtual. Αυτό είναι, virtual.
Virtual κάνεις όσες methods θέλεις/ξέρεις από πριν να κάνεις overriding


Σωστο παράδειγμα με Virtual Functions
Κώδικας: Επιλογή όλων
                                                            
#include <iostream>
using namespace std;

class Thilastiko
{
   public:
      Thilastiko() {}   // constructor
      virtual ~Thilastiko() {}   // Destructor PANTA VIRTUAL
      virtual void Speak() const { cout << "Thilastiko milaei" << endl; }
};

class Skylos : public Thilastiko
{
   public:
      Skylos() {}   // constuctor
      virtual ~Skylos() {}   //destructor PANTA VIRTUAL
      virtual void Speak()   const { cout << "Woof Woof Woof" << endl;}
};

int main()
{
   
   Thilastiko *Beetoven = new Skylos;
   Beetoven -> Speak();   // palia grafame Beetoven.Speak();
   
   return 0;
}


##########################################################################
## Output: Woof Woof Woof
##########################################################################





Προσβαση στη hidden virtual base method
Example

Κώδικας: Επιλογή όλων
#include <iostream>
using namespace std;

class Thilastiko
{
   public:
      Thilastiko() {}   // constructor
      virtual ~Thilastiko() {}   // Destructor PANTA VIRTUAL
      virtual void Speak() const { cout << "Thilastiko milaei" << endl; }
};

class Skylos : public Thilastiko
{
   public:
      Skylos() {}   // constuctor
      virtual ~Skylos() {}   //destructor PANTA VIRTUAL
      virtual void Speak()   const { cout << "Woof Woof Woof" << endl;}
};

int main()
{
   
   Thilastiko *Beetoven = new Skylos;
   Beetoven -> Speak();   // palia grafame Beetoven.Speak();
   Beetoven->Thilastiko::Speak();   // palia grafame Beetoven.Thilastiko::Speak();
   
   return 0;
}


#########################################################################
## Output: Woof Woof Woof
## Thilastiko milaei
#########################################################################




Example Dynamic Binding
Κώδικας: Επιλογή όλων
#include <iostream>
using namespace std;

class Thilastiko
{
   public:
      Thilastiko() {}   // constructor
      virtual ~Thilastiko() {}   // Destructor PANTA VIRTUAL
      virtual void Speak() const { cout << "Thilastiko milaei" << endl; }
};

class Skylos : public Thilastiko
{
   public:
      Skylos() {}   // constuctor
      virtual ~Skylos() {}   //destructor PANTA VIRTUAL
      void Speak()   const { cout << "Woof Woof Woof" << endl;}
};

class Cat : public Thilastiko
{
   public:
      Cat() {}   // constructor
      virtual ~Cat() {}   //Destructor PANTA VIRTUAL
      virtual void Speak() const { cout << "Niaou Niaou Niaou" << endl; }
};

class Horse : public Thilastiko
{
   public:
      Horse() {}   // constructor
      virtual ~Horse() {}   //Destructor PANTA VIRTUAL
      virtual void Speak() const { cout << "Xlimintrisma" << endl; }
};

class Cow : public Thilastiko
{
   public:
      Cow() {}      // constructor
      virtual ~Cow() {}   // Destructor PANTA Virtual
      virtual void Speak() const { cout << "Mooooo Mooooo Mooooo" << endl; }
};

int main()
{
   
   // Static
   // Thilastiko *ptr = new Skylos;
   
   // Dynamic Binding Runtime
   //The Reason you learn subclass pointer definition
   //

   Thilastiko  *pinakas[5]; // Pinakas (se periptosi pou den to ksereis, ola ta arrays einai pointers)
                     // pou krataei dedomena typoy Thilastiko
   Thilastiko *ptr;      // pointer tupou Thilastiko , edo 8a grafame Thilastiko *ptr = new Skylos
   int choice, i;
   cout << "Please choose: " << endl;
   for(i=0; i<5; i++)
   {
      cout << " Skylos(1)   Gata(2)      Alogo(3)   Agelada(4) :";
      cin >> choice;
      switch (choice)
      {
         case 1:      ptr = new Skylos;   // to ptr einai idi Thilastiko *ptr
                  break;
         case 2:      ptr = new Cat;   
                  break;
         case 3:      ptr = new Horse;
                  break;
         case 4:      ptr = new Cow;
                  break;
         default:      ptr = new Thilastiko;
                  break;
      }
      pinakas[i] = ptr;
   }
   for(i=0; i<5; i++)
   {
      pinakas[i] -> Speak();
   }
   
   return 0;
}




Output:
Please choose:
Skylos(1) Gata(2) Alogo(3) Agelada(4) :1
Skylos(1) Gata(2) Alogo(3) Agelada(4) :2
Skylos(1) Gata(2) Alogo(3) Agelada(4) :3
Skylos(1) Gata(2) Alogo(3) Agelada(4) :4
Skylos(1) Gata(2) Alogo(3) Agelada(4) :5
Woof Woof Woof
Niaou Niaou Niaou
Xlimintrisma
Mooooo Mooooo Mooooo
Thilastiko milaei




Σημαντικά πράγματα που πρέπει να ξέρεις για τις virtual functions
Οταν γράφεις: Thilastika *ptr = new Dog;
Tότε φτιάχνετε ένα κουτί μέσα στην μνήμη του υπολογιστή (heap) το οποίο είναι χωρισμένο σε δύο μέρη
το ένα μέρος είναι το 1)Thilastiko Part και το δευτερο μέρος είναι 2)Dog Part. Αυτά τα δύο βρίσκονται μέσα στο κουτί
το οποίο κουτί είναι το αντικείμενο Dog

Όταν κανω virtual μια method της base class Thilastiko πχ την void Speak(), παω την αλλαζω σε virtual void Speak()
τότε το αντικείμενο πρέπει να είναι σε θέση να ακουλοθεί τα ίχνη αυτής της virtual void Speak(). Πώς το πετυχaiνει ;

Αρχικά όπως μάθαμε πιο πανω, καλείται ο Base Constructor (aka Thilastika Constructor)
καλείται αυτός, τότε ο compiler φτιάχνει έναν πίνακα που των χωρίζει σε 2 μέρη (οπως πριν)
αυτός ο πίνακας λέγεται v-table του Thilastika. Τι περιέχει αυτός ο πίνακας όμως ;
Είναι χωρισμένος σε 2 μέρη. Το ένα μέρος του λέγεται 1)Thilastiko και το άλλο λέγεται 2)v-ptr
Το v-ptr είναι ο pointer που δείχνει την virtual method. Δηλαδη κρατάει την διεύθυνση της virtual method (& Speak)
Μετά καλείται ο Derived Constructor (aka Dog Constructor)
και ο compiler κάνει παλι το ίδιο. Φτιάχνει έναν πίνακα που λέγεται v-table του αντικεμενου Dog
Αυτός είναι χωρισμένος σε δυο μέρη. Το 1)Dog και το αλλο 2)v-ptr
To v-ptr δείχνει στην virtual method Speak της Base Class , δηλαδή δείχνει στο &Mammal:Speak ενώ οι άλλες
derived έχουν διεύθυνση &Dog:Move. Προσεχε, το v-ptr δείχνει μόνο στην virtual method void Speak.


#############################################################################
## Κατι ακομα: Αν εχεις μια derived method Move που δεν υπάρχει στην base class τότε δεν μπορεις να την καλεσεις
## με κανεναν τροπο. Τι θα κανεις ; Θα το μαθεις μετα, λεγεται typeCasting.
#############################################################################



## 0x08 --Multiple Inheritance ##
####################

Εχεις δυο classes: Αλογο και Πτηνό. Θες να φτιαξεις μια τριτη class Πήγασσος. Τι ειναι ομως αυτο ; Πουλί ή Αλογο ;
είναι και απο τα δύο. Γράφεται:

class Pigasos : public Alogo, public Pouli


Παράδειγμα

Κώδικας: Επιλογή όλων
                                                                           
#include <iostream>
using namespace std;

class Alogo
{
   public:
      Alogo() {}      // constructor
      virtual ~Alogo() {}   // destructor

      // Accessors Methods
      // variemai na grafo

      // Other Methods
      virtual void xlimintrisma() const { cout << "Xlimintrizo\n"; }
};

class Pouli
{
   public:
      Pouli() {}      // Constructor
      virtual ~Pouli() {}   // Destructor

      // Accessors
      // variemai na grafo

      // Other Methods
      virtual void petao() const { cout << "Petao\n"; }
};

class Pigasos : public Alogo, public Pouli
{
   public:
      Pigasos() {}      // constructor
      virtual ~Pigasos() {}   // destructor
};

int main()
{
   Alogo * ptrAlogo;
   Pouli * ptrPouli;
   Pigasos * ptrPigasos;
   int choice, i;
   cout << "Please choose:\n";
   cout << "Alogo(1), Pouli(2), Pigasos(3) : ";
   cin >> choice;
   switch (choice)   {
      case 1:      ptrAlogo = new Alogo;
            break;
      case 2:      ptrPouli = new Pouli;
            break;
      case 3:      ptrPigasos = new Pigasos;
            break;
      default:   cout << "Error input. Program terminated. . . .";
            return -1;
            break;
   }
   
   if (choice == 1)   { ptrAlogo -> xlimintrisma(); }
   if (choice == 2)   { ptrPouli -> petao(); }
   if (choice == 3)   { ptrPigasos -> xlimintrisma(); ptrPigasos -> petao(); }
   

   return 0;
}





Virtual Classes
Animal
Horse Bird <--- Horse and Bird derived απο την Animal, και μεταξυ τους εχουν ως μωρό τους την Pegasus
Pegasus
Για να εξασφαλίσεις οτι classes προέρχονται από την ίδια κοινή base class, τις κάνω virtual
Αφού ξέρεις από πριν ότι από μια class θα ξεπεταχτούν αρκετές subclasses και όχι απλά μόνο μία, τότε
είναι καλή τακτική να τις κάνεις virtual. ##
Example

Κώδικας: Επιλογή όλων
#include <iostream>
using namespace std;

enum XROMA { ASPRO, MAVRO, KAFE };

class Zoa      // common base class for both Alogo & Pouli
{
   public:
      Zoa() {}
      Zoa( int age ):itsAge(age) {}
      virtual ~Zoa(){}
      virtual int GetAge() const { return itsAge; }
      virtual void SetAge( int mAge) { itsAge = mAge; }
   protected:
      int itsAge;
};

class Alogo : virtual public Zoa
{
   public:
      Alogo() {}
      Alogo(int age, XROMA color):itsAge(age), itsColor(color)   {}
      virtual ~Alogo()   {}
      virtual int GetAge() const { return itsAge; }
      virtual void SetAge( int mAge )   { itsAge = mAge; }
      virtual XROMA GetColor()  const { return itsColor; }
      virtual void SetColor( XROMA mColor) { itsColor = mColor; }
   protected:
      XROMA itsColor;
      int itsAge;
};

class Pouli : virtual public Zoa
{
   public:
      Pouli() {}
      Pouli(int age, XROMA color): itsColor(color), itsAge(age) {}
      virtual ~Pouli() {}
      virtual int GetAge() const { return itsAge; }
      virtual void SetAge( int mAge) { itsAge = mAge; }
      virtual XROMA GetColor() const { return itsColor; }
      virtual void SetColor( XROMA mColor ) { itsColor = mColor; }
   protected:
      XROMA itsColor;
      int itsAge;
};

class Pigassos : public Alogo, public Pouli
{
   public:
      Pigassos() {}
      Pigassos(int age, XROMA body, XROMA ftera) { body = Alogo::itsColor; ftera = Pouli::itsColor; itsAge = age; }
      virtual ~Pigassos() {}
      virtual int GetAge() const { return itsAge; }
      virtual void SetAge( int mAge) { itsAge = mAge; }
      virtual XROMA GetColorBody() const  { return Alogo::itsColor; }
      virtual void SetColorBody(XROMA mbody) { Alogo::itsColor = mbody; }
      virtual XROMA GetColorFtera() const { return Pouli::itsColor; }
      virtual void SetColorFtera(XROMA mftera) { Pouli::itsColor = mftera; }
   protected:
      int itsAge;
};

int main()
{
   Alogo *pAlogo = new Alogo(2,KAFE);
   Pigassos *pPigas = new Pigassos(12, ASPRO, ASPRO);
   cout   << "O Pigassos exei ilikia " << pPigas -> GetAge()
      << " xroma somatos " << pPigas -> GetColorBody()
      << " xroma fteron " << pPigas -> GetColorFtera() << endl;
   cout << "\nTo alogo exei xroma: " << pAlogo -> GetColor () ;
   pAlogo -> SetColor( MAVRO );
   cout << "\nTo alogo exei xroma: " << pAlogo -> GetColor () ;
   cout << "\nO Pigassos exei xroma somatos: " <<  pPigas -> GetColorBody() << endl;
   return 0;
}




#######################################################################

Abstract Class
Συχνα χρειαζεται να φτιαξετε μια class σαν οδηγο. Δεν προκειται ποτε να φτιαξετε αντικειμενο για αυτη την
αλλά θέλετε να την χρησιμοποιήσετε για να κρατάτε έναν οδηγό/πατούρα των methods
πχ εχω μια class abstract που λεγεται Shape. Απο κει βγαζω 2 derived class Κυκλος και Ορθογωνιο
για τον σχεδιασμό τους και τα γεωμετρικα χαρακτηριστικά χρησιμοποιηώ τις methods του Shape
Πες τώρα ότι θελεις να φτιαξεις μια class Τετραγωνο. Αυτη όμως είναι μια ειδικη περίπτωση του ορθογωνίου
οποότε γιατι να την ξαναγράφεις ; Αρκεί να την περάσεις (μεσω constructor overloading) στο ορθογώνιο


Pure Function: Βάζουμε τις methods της Abstract Class. Μετα απο αυτο ειναι αδυνατο να δημιουργηθεί
αντικείμενο της abstract class.
Παράδειγμα
Κώδικας: Επιλογή όλων

      // Method to be Override
      virtual void Draw() = 0;   // pure function
      private:
};

//   /   /   /   /   /   /   /   /   /   /   /
// Derived Classes
// ///////////////////////
//1st  Derived Cycle   //
// //////////////////////
class Circle : public Shape   // publicaly access type of Shape
{
   public:
   Circle(int radius):itsRadius(radius) {}      //call -> Circle(5) ,  5=radius
   virtual ~Circle(){}
   
   // Override Shape Accessors
   virtual long GetArea() { return 3 * itsRadius * itsRadius; } // 3*5*5 = 75
   virtual long GetPerim() { return 6 * itsRadius; }      // 6*5 = 30

   // Override Shape Method Draw
   virtual void Draw();       // 8a grapso meta ti 8a kanei, edo den exo xoro
   private:
   int itsRadius;         // to 5 8a isxuei mono gia autin tin class.
   int itsCircumference;
};

// Implementation of Method Draw of the Circle class
void Circle::Draw()
{
   cout << "Circle drawing routine here!\n";
}

/////////////////////////////////
// 2i Derived Class Rectangle    //
// ///////////////////////////////
class Rectangle : public Shape
{
   public:
      Rectangle(int len, int width):itsLength(len), itsWidth(width) {}   //Rectangle(5,10) 5=length, 10 = width
      virtual ~Rectangle() {}

      // Overriding accessors
      virtual long GetArea() { return itsLength * itsWidth; }   // 5*10 = 50
      virtual long Getperim() { return 2*itsLength + 2*itsWidth; }   // 5*2 + 10 *2 = 30
      
      // New Methods !!!!!
      virtual int GetLength() { return itsLength; }   // GetLength = 5,  epeidi to 5 den pernaei (private) stin derived square 8a perasei i method
      virtual int GetWidth() { return itsWidth; }   // GetWidth = 10. to 10 den pernaei (private) stin derived square 8a perasei i method
      
      // Overriding DrawMethod
      virtual void Draw();   // 8a tin anaptikso meta
   private:
      int itsLength;      // epeidi den pernane auta, ( logos einai epeidi einai private)
      int itsWidth;      // 8a peraso tis methods pou kratane autous tous arithmous (giati na min kano protected omos o anomalos ? )
};

// Implementation of Draw  Method (Rectangle Class)
void Rectangle::Draw()   // zografizei ena tetragono me 5 kai 10
{
   for(int i =0; i<itsLength; i++)
   {
      for ( int j =0; j<itsWidth; j++)
      {
         cout << "x";
      }
      cout << endl;
   }
}

// Special Class Square
// Derived from Rectangle which derived from Shape
class Square : public Rectangle
{
   public:
      Square(int len);   // square(5)  5 = lenth
      Square(int len, int width);   // square(5,5) 5=length=width
      ~Square() {}
      
      // Override accessors
      long GetPerim() { return 4 * GetLength(); } // 4*5 = 20
};
// paratiro oti edo den exo tis class:
// GetArea
// void Draw --> simantiko! Giati arage den tin exo ?

// Implementation of Square Constructor
// Overloading 1
Square::Square(int len):Rectangle(len,len) {}   //trofodoti to len tou square os Length=Width gia tin Rectangle

//Overloading 2
Square::Square(int len, int width):Rectangle(len,width) //trofodototei ta len kai width tou Square sta antistoixa tou Rectangle
{
   if( GetLength() != GetWidth())   // An to Rectangle exei width = length
   {
      cout << "This is not a rectangle\n";
   }
}

int main()
{
   int choice;
   bool fQuit = false;
   Shape *pointer;
   cout << "(1)Circle (2)Rectangle (3)Square (0)Quit: ";
   cin >> choice;
   while(!fQuit) {

      switch(choice){
      case 0: fQuit = true;
            break;
      case 1: pointer = new Circle(5);
               break;
      case 2: pointer = new Rectangle(4,6);
               break;
      case 3: pointer= new Square(5);
         break;
      default:
         cout << "Please enter a number [0-3]" << endl;
         break;
      }

      if( !fQuit){
         pointer ->Draw();
         fQuit = true;
      }
      delete pointer;
      pointer = 0;
      cout << endl;
      

   }
   return 0;
}




## 0x9 --Static Function / Members ##
#######################
Μερικές φορές θέλεις να έχεις μια μεταβλητή ή μια συνάρτηση (κάτι σαν globe) που να μπορεί να ελέγχει ανα
πάσα στιγμή κάποια δεδομένα που σχετίζονται με αντικείμενα ίδιου τύπου (πχ εχεις 5 γάτες)
Αυτό γίνεται με static functions καθώς μεσω αυτών μπορείς να τις καλέσεις είτε μεσω object είτε μεσω class
Ακολουθεί ένα παράδειγμα όπου οι static functions, χρησιμοποιούν τις static variables. Αν τις τελευταιες τις βαλω
public τότε θα είναι διαθεσιμες σε όλους. Συνηθίζεται να είναι είτε private είτε protected.

Example
Κώδικας: Επιλογή όλων
#include <iostream>
using namespace std;

class Gata
{
   public:
      Gata() { PosesGates++; }   // constructor
      ~Gata() { PosesGates--; }   // destructor

      // Static Function
      // Accessed through Object or through Class itself
      static int GetPosesGates() { return PosesGates; }
      // ^^^ DEN EINAI POTE const
      
   private:
      static int PosesGates;
};

// Initialize static
int Gata::PosesGates = 0;

int main()
{
   
   //Ftiaxno mia Gata Object
   Gata Lougritia;

   //Kalesma static meso Class
   cout << Gata ::GetPosesGates() << endl;

   //kalesma static meso Object
   cout << Lougritia.GetPosesGates() << endl;

   return 0;
}





## 0x10 --Pointer to Function ##
####################
## Ειναι πολυ χρησιμο για δυναμική επιλογή του χρήστη ποια function θελει να καλέσει
## οποτε φτιαχνεις εναν pointer ο οποιος δειχνει σε μια function με ίδιο return type και παραμέτρους
####################################################################


πχ int pros8esi (int x, int y) { return x + y; } είναι μια function
φτιαχνω εναν pointer στην function : int (* pointer2Function) (int, int)
μετα βαζω τον pointer να δειχνει στην συγκεκριμενη function: pointer2Function = pros8esi
και για να καλεσω την συναρτηση, καλω τον pointer που δειχνει στην συναρτηση: pointer2Function(2,5)
##########################################################################
Παράδειγμα:

Κώδικας: Επιλογή όλων
#include <iostream>
using namespace std;

void Tetragono (int &x, int &y)
{
   x = x * x;
   y = y * y;
}

void Kubos (int &x, int &y)
{
   int temp;

   temp = x;
   x = x * x;
   x = x * temp;

   temp = y;
   y = y * y;
   y = y * temp;
}

void Swap(int &x, int &y)
{
   int temp;

   temp = x;
   x = y;
   y = temp;
}

void Read(int &TimiEna, int &TimiDuo)
{
   cout << "Dose nea timi Ena: ";
   cin >> TimiEna;
   cout << "Dose nea timi Duo: ";
   cin >> TimiDuo;
}

void Print(int x, int y)
{
   cout << "x: " << x << " y: " << y << endl;
}

int main()
{
   // pointer to function
   // which returns void
   // parameters : int , int
   void (* pFunc) (int &, int &);
   bool fQuit = false;

   int TimiEna = 1, TimiDuo = 2;
   int choice;

   while (!fQuit)
   {
      cout <<" (0)Quit (1)Allagi Timon (2)Tetragono (3) Kubos (4)Swap: ";
      cin >> choice;

      switch(choice)
      {
         case 1: pFunc = Read;
            break;
         case 2: pFunc = Tetragono;
            break;
         case 3: pFunc = Kubos;
            break;
         case 4: pFunc = Swap;
            break;
         default: fQuit = true;
      }

      if(!fQuit)
      {
         Print(TimiEna, TimiDuo); // kalo tin function Print me klisi Timis
         pFunc(TimiEna, TimiDuo); // kalei tin function pou deixnei apo prin meso tou pointer
         Print(TimiEna, TimiDuo);
      }
   }
   return 0;
}


Να σημειωσω οτι ειναι αρκετα επικυνδινο αυτο και πλεον (τουλαχιστον στο Qt) γινεται μεσω SLOTS - METHODS .

Αν θέλετε κι αλλα πείτε μου.
Αν έχετε διορθώσεις πείτε μου.
Αν διαφωνείται με κάτι πείτε μου.
Αν αν αν αν ... στείλτε ενα PM.
BlackSlash13
babeTUX
babeTUX
 
Δημοσιεύσεις: 17
Εγγραφή: 09 Ιουν 2008, 19:01
Εκτύπωση

Re: Object Oriented Programming [Τα Βασικα]

Δημοσίευσηαπό ilpara » 15 Αύγ 2008, 15:42

Απλώς συγχαρητήρια :D
Συνέχισε!
*Oδηγίες προς Nεοεισερχόμενους*ΟδηγοίLive chat (IRC)
⇛ Linux: Μέτριο ┃ Προγραμματισμός: Όχι ┃ Αγγλικά: Καλά
⇛ Ubuntu 12.04 32bit
⇛ Dell M4300: T7500 (2.2GHZ 4MB) ┃ 2GB ┃ NVIDIA Quadro FX 360M (256MB) ┃ Intel 4965 ┃ 15.4" WUXGA
Άβαταρ μέλους
ilpara
powerTUX
powerTUX
 
Δημοσιεύσεις: 2250
Εγγραφή: 11 Μάιος 2008, 11:43
Τοποθεσία: Αθήνα-Βύρωνας
IRC: ilpara
Εκτύπωση

Re: Object Oriented Programming [Τα Βασικα]

Δημοσίευσηαπό kalakouentin » 15 Αύγ 2008, 16:26

Salute. Τεράστιος. Εύγε.
Εικόνα
Γνώσεις ⇛ Linux: Συμπαθητικές ┃ Προγραμματισμός: Συμπαθητικότερες ┃ Αγγλικά: Αστέρι
Λειτουργικό ⇛ Ubuntu 10.04 32bit σε HP nw9440 ┃ Ubuntu 10.04 32bit σε Toshiba Satellite U400┃ SLED 11 64bit σε Dell OptiPlex 780
kalakouentin
seniorTUX
seniorTUX
 
Δημοσιεύσεις: 545
Εγγραφή: 05 Ιούλ 2008, 05:50
Εκτύπωση

Re: Object Oriented Programming [Τα Βασικα]

Δημοσίευσηαπό taratatzoum » 15 Αύγ 2008, 18:06

Εικόνα


keep going BlackSlash13 ;)
Ιστολόγιο
1 Γνώσεις → Linux: Προχωρημένος ┃ Προγραμματισμός: Μέτριος ┃ Αγγλικά: Προχωρημένος
2 Λειτουργικό → Slackware 13.37.0 64-bit (el_GR.utf-8)
3 Προδιαγραφές → CPU: 8x Intel Core i7 CPU Q 740 1.73GHz ‖ RAM 3894 MiB ‖ Dell Inc. - Dell Inc. Inspiron N5010
4 Κάρτες γραφικών: ATI Redwood [Radeon HD 5600 Series] ⎨1002:68c1⎬
5 Δίκτυα: wlan0: Broadcom BCM4313 802.11b/g/n Wireless LAN Controller ⎨14e4:4727⎬ ⋮ eth0: Realtek RTL8101E/RTL8102E PCI Express Fast Ethernet controller ⎨10ec:8136⎬
taratatzoum
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 849
Εγγραφή: 10 Μάιος 2008, 20:29
Τοποθεσία: Χανιά
Launchpad: rizitis
IRC: rizitis or rtz
Εκτύπωση

Re: Object Oriented Programming [Τα Βασικα]

Δημοσίευσηαπό sudobash » 16 Αύγ 2008, 00:09

Εξαιρετικό tutorial.. συγχαρητήρια!
Ubuntu 9.10 32bit | 2 x Intel Core 2 Duo T5500 @ 1.66GHz | 2GB DDR2 RAM | Intel 950 Graphics
Richard Stallman wrote the compiler God used. The Big Bang was the Universe's first segfault.
Άβαταρ μέλους
sudobash
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 876
Εγγραφή: 13 Μάιος 2008, 20:11
Τοποθεσία: Κρήτη
Εκτύπωση

Re: Object Oriented Programming [Τα Βασικα]

Δημοσίευσηαπό ftso » 19 Αύγ 2008, 11:17

Άντε μπας και μάθουμε και καμιά C++...
Μπράβο σου! :D
Άβαταρ μέλους
ftso
Επίτιμο μέλος
Επίτιμο μέλος
 
Δημοσιεύσεις: 6409
Εγγραφή: 12 Μάιος 2008, 13:40
Τοποθεσία: Αθήνα
IRC: ftso
Εκτύπωση

Re: Object Oriented Programming [Τα Βασικα]

Δημοσίευσηαπό sokoban4ever » 23 Φεβ 2009, 02:58

Συγχαρητάρια ρε συ καλός οδηγός :) ;)
Θέλουμε και μπορούμε να έχουμε μια καλύτερη ζωή και όσο θα ζούμε θα προσπαθούμε να την αποκτήσουμε ακόμα και αν πεθάνουμε προσπαθώντας, και αν κάποια στιγμή λιγίσουμε έχουμε το επίπεδο να πούμε κουράστηκα λίγο να ,να ξαποστάσουμε , ώστε να συνεχίσουμε πάλι δυνατοί ξανά.

Μήνυμα με αγάπη και αληλλεγγύη σε όλους τους ανθρώπους από όλους τους λαούς , ιδίως του Ελληνικού.
Άβαταρ μέλους
sokoban4ever
Επίτιμο μέλος
Επίτιμο μέλος
 
Δημοσιεύσεις: 2331
Εγγραφή: 13 Φεβ 2009, 02:22
Εκτύπωση

Re: Object Oriented Programming [Τα Βασικα]

Δημοσίευσηαπό TzaB » 21 Μαρ 2009, 22:43

Συγχαρητήρια για τη δουλειά σου. Βοηθάει πολύ ως συμπλήρωμα όταν αρχίζει κάποιος να μαθαίνει OOP.
Άβαταρ μέλους
TzaB
babeTUX
babeTUX
 
Δημοσιεύσεις: 11
Εγγραφή: 28 Ιουν 2008, 01:05
Τοποθεσία: Θεσσαλονίκη
Εκτύπωση


Επιστροφή στο Οδηγοί - How to - Tutorials