Pages: [1]   Go Down
Author Topic: Classi derivate  (Read 573 times)
0 Members and 1 Guest are viewing this topic.
MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buongiorno a tutti,

Stavo facendo degli esperimenti con le classi derivate, ho visto che il core di arduino ne fà uso, pertanto ho pensato che si potessero utilizzare anche normalmente negli sketch.
Ho fatto un esperimento, creando una classe base 'animale' e provando a crearne una derivata 'cane' ma ottengo un errore in compilazione.
Allego sorgenti delle classi

animale.h
Code:
class animale
{
private:

public:
animale();
virtual ~animale();
void chiama();
        virtual int zampe();
};

animale.cpp
Code:
#include "animale.h"

animale::animale()
{
// TODO Auto-generated constructor stub
}

animale::~animale()
{
// TODO Auto-generated destructor stub
}

void animale::chiama()
{
  // chiama l'animale
}

cane.h
Code:
#include "animale.h"

class cane: public animale
{
private:

public:
cane();
virtual ~cane();
        int zampe();
};

cane.cpp
Code:
#include "cane.h"

cane::cane()
{
// TODO Auto-generated constructor stub
}

cane::~cane()
{
// TODO Auto-generated destructor stub
}

int cane::zampe()
{
  return 2;
}
L'errore che ritorna è :
animale.cpp.o:(.rodata._ZTV7animale+0x8): undefined reference to `animale::zampe()'


Mi è sfuggito qualcosa ?
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Parma
Offline Offline
Edison Member
*
Karma: 20
Posts: 2359
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In animale.h hai una funzione
virtual int zampe();
che non è implementata, se non vuoi implementarla devi trasformare la classe animale in astratta (non potrai istanziarla)

Ciao
Logged

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Già , ma non mi pare che ci sia modo esplicito di creare una classe astratta.

dichiarando invece

Code:
virtual int zampe() = 0 ;

compila correttamente ma non ottengo quello che voglio, ovvero vorrei che il compilatore si incatsasse se dichiaro una classe derivata che non implementa una funzione prevista nella classe base ma non implementata (esattamente il concetto di una classe astratta insomma).



 
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Parma
Offline Offline
Edison Member
*
Karma: 20
Posts: 2359
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Con
virtual int zampe() = 0 ;
la classe diventa astratta, non devi scrivere abstract come in altri linguaggi di programmazione.
Il compilatore non ti da errori perché probabilmente ottimizza il codice e non compila le classi non utilizzate, se provi ad aggiungere:

Code:
cane c;
c.zampe();

vedrai che se non è implementata la funzione zampe e nella classe base è definita come una funzione virtuale pure (con =0) ti darà sicuramente errore
Logged

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si esattamente.

Ora il cerchio si chiude.

Praticamente dichiarando un metodo virtual = 'qualcosa' la classe diventa astratta e funziona tutto regolarmente come dovrebbe essere.
Ma a questo punto mi domando, se dichiarando una funzione di qualsiasi tipo (anche void) in questa maniera :

Code:
virtual animale.zampe() = 'qualcosa';

sono comunque obbligato a reimplementare quella funzione nella classe derivata , e alla stessa maniera non posso instanziare la classe base, a che cavolo serve mettere = 'qualcosa' ????

Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Parma
Offline Offline
Edison Member
*
Karma: 20
Posts: 2359
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Non esiste un "= qualcosa", per dire al compilatore che la funzione è virtuale pura, che comporta che la classe sarà astratta, bisogna scrivere ad esempio

Code:
virtual void zampe() = 0;

il tipo e il nome della funzione non hanno importanza, possono essere come desideri, l'importante è la keyword "virtual" e "=0" per rendere la funzione virtuale pura.

Avere classi astratte è molto utile, senza bisogno che scrivo troppo su internet trovi molto materiale sulla programmazione ad oggetti

Ciao
Logged

Parma
Offline Offline
Edison Member
*
Karma: 20
Posts: 2359
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Non puoi instanziare la classe base ma tramite i puntatori puoi trattare un oggetto derivato (es. cane) come un oggetto base (es. animale)
Per farti capire l'utilità, se hai uno zoo e vuoi far la conta delle zampe non devi gestire in modo particolare tutti gli animali ma puoi semplicemente fare affidamento sul fatto che tutti gli animali hanno un metodo zampe() come definito nella classe animale e fare qualcosa tipo:

Code:
cane c;
int totZampe = 0;
animale *a; // animale può puntare ad un cane o ad un gatto (se deriva da animale)
a = &c;   // in questo caso puntiamo ad un cane
totZampe += a->zampe();  // l'istruzione è la solita sia che il puntatore "a" punta ad un cane o un gatto

ciao
« Last Edit: November 21, 2012, 09:07:02 am by flz47655 » Logged

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Non fraintendere, non metto in discussione l'utilità delle classi astratte , a dimostrazione lo è il fatto che le stò usando!

Quello che non avevo capito era che come hai detto tu nell'intervento precedente non può essere  :

Code:
virtual int zampe() = 'qualcosa';

ma deve essere proprio :
Code:
virtual int zampe() = 0;

A questo punto l'unica cosa oggettivamente sindacabile è la sintassi poco intuitiva, ma se alla fine quello deve essere, quello sarà!
avrei preferito il qualificatore abstract a livello di classe... ma sono gusti miei personali...

Quello che avevo erroneamente capito è che con = 0 si andasse ad impostare il valore ritornato dalla chiamata a quel metodo qualora non fosse stato reimplementato esplicitamente dalla classe derivata

« Last Edit: November 21, 2012, 01:37:28 pm by niki77 » Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sì, in effetti la sintassi del C++ per indicare che una funzione è pure virtual è decisamente pessima smiley-wink

Solo una precisazione (se quanto sto per dire ti è già chiaro, ingoralo smiley ). Il fatto di avere un metodo virtual non rende astratta una classe. La parola chiave "virtual" attiva il meccanismo del polimorfismo.
Una classe è astratta quando ha almeno un metodo astratto (cioè dichiarato con la convenzione virtual / = 0).
Logged

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie , sia a tuxduino che a flz47655.

Le cose quando sono giuste e ben spiegate non sono mai superflue, e pertanto non vanno ignorate!
 smiley-wink

Non bisogna mai perdere di vista il fatto che un forum non è un call-center di assistenza, quello che abbiamo dibattuto può essere d'aiuto anche per altri, non solo fine alla risoluzione del mio specifico problema.
 smiley-cool
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

+1
Logged

Pages: [1]   Go Up
Jump to: