martedì 2 settembre 2014

Funzioni virtuali in C++ (ripasso)

Dunque, se io istanzio la classe base e la classe derivata, ognuna esegue i metodi che le competono.
Ma se io istanzio la classe derivata come classe base, ossia creo una variabile di tipo classe base e le attribuisco invece una classe derivata, cosa succede?
Dovrebbe eseguire sempre i metodi della classe base.

C++
#include "iostream"
using namespace std;

class Base{
public:
 void metodo(){
 cout << "Io sono il metodo della classe Base" << endl;
 getchar();
 }
};

class Derivata: public Base{
public:

 void metodo(){
 cout << "Io ridefinisco il metodo della classe Base" << endl;
 getchar();

 }
 
};

void main(){
 Base miaBase;
 Derivata miaDerivata;
 Base x;
 x= miaDerivata;

 miaBase.metodo();
 miaDerivata.metodo();
 x.metodo();

} 
Io sono il metodo della classe Base

Io ridefinisco il metodo della classe Base

Io sono il metodo della classe Base




C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    class Base
    {
        public void metodo()
        {
            Console.WriteLine("Io sono il metodo della classe Base");
            Console.ReadLine();
        }
    }

    class Derivata:Base{

        public void metodo()
        {
            Console.WriteLine("Io ridefinisco il metodo della classe Base");
            Console.ReadLine();

        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            Base miaBase=new Base();
            Derivata miaDerivata=new Derivata();
            Base x;
            x = miaDerivata;

            miaBase.metodo();
            miaDerivata.metodo();
            x.metodo();
        }
    }
}
Io sono il metodo della classe Base

Io ridefinisco il metodo della classe Base

Io sono il metodo della classe Base




Ma proviamo in C++ coi puntatori:
#include "iostream"
using namespace std;

class Base{
public:
 void metodo(){
 cout << "Io sono il metodo della classe Base" << endl;
 getchar();
 }
};

class Derivata: public Base{
public:

 void metodo(){
 cout << "Io ridefinisco il metodo della classe Base" << endl;
 getchar();

 }
 
};

void main(){
 Base * miaBase=new Base;
 Derivata * miaDerivata= new Derivata;
 Base * x;
 x= miaDerivata;

 miaBase->metodo();
 miaDerivata->metodo();
 x->metodo();

} 
Io sono il metodo della classe Base

Io ridefinisco il metodo della classe Base

Io sono il metodo della classe Base


Anziché attribuire a un nuovo puntatore il valore di un altro, creiamo tramite allocazione dinamica della memoria una nuova istanza della classe:
...
void main(){
 Base * miaBase=new Base;
 Derivata * miaDerivata= new Derivata;
 Base * x = new Derivata;

 miaBase->metodo();
 miaDerivata->metodo();
 x->metodo();

}
Io sono il metodo della classe Base

Io ridefinisco il metodo della classe Base

Io sono il metodo della classe Base


Sempre uguale, dunque: attribuendo un oggetto di tipo classe derivata a una variabile di tipo classe base, o mettendone l'indirizzo in un puntatore tipo classe base, verranno sempre eseguiti i metodi della classe base.

Adesso ovviamo a questo con le funzioni virtuali:
#include "iostream"
using namespace std;

class Base{
public:
 virtual void metodo(){
 cout << "Io sono il metodo della classe Base" << endl;
 getchar();
 }
};

class Derivata: public Base{
public:

 void metodo(){
 cout << "Io ridefinisco il metodo della classe Base" << endl;
 getchar();

 }
 
};

void main(){
 Base miaBase;
 Derivata miaDerivata;
 Base x;
 x=miaDerivata;

 miaBase.metodo();
 miaDerivata.metodo();
 x.metodo();
}
Io sono il metodo della classe Base

Io ridefinisco il metodo della classe Base

Io sono il metodo della classe Base


Con le variabili il risultato è sempre quello di prima: la classe Base esegue i metodi della classe Base.
Vediamo con i puntatori:
.....
void main(){
 Base * miaBase=new Base;
 Derivata * miaDerivata=new Derivata;
 Base * x = new Derivata;

 miaBase->metodo();
 miaDerivata->metodo();
 x->metodo();
}
Io sono il metodo della classe Base

Io ridefinisco il metodo della classe Base

Io ridefinisco il metodo della classe Base


Ecco! Con le funzioni virtuali, a patto che si usino i puntatori e non le variabili, in C++ l'istanza della classe derivata eseguita come tipo base esegue i metodi della classe derivata.

Nessun commento:

Posta un commento