PDA

View Full Version : [[C++] Ereditarietà e polimorfismo - problema


mistergks
02-02-2016, 19:01
Sto svolgendo un esercizio in C++ per la programmazione orientata agli oggetti.



Traccia:

Un giocatore ha nome, età e un valore che dipende dal ruolo del giocatore e dall'età.

Progettare la classe Giocatore fornendo solo la definizione (Giocatore.h) tenendo presente che il sistema deve essere flessibile all'aggiunta di un nuovo ruolo.

Inserire nella classe Giocatore tutti i metodi che si ritengono opportuni motivandone l'aggiunta.



Ho risolto cosi':

file Giocatore.h



#ifndef GIOCATORE_h

#define GIOCATORE_H



class Giocatore{



protected:

string nome;

int eta;

int valore;



public:

string getNome() const;

int getEta() const;

int getValore() const;



void setNome(string n);

void setEta(int e);

void setValore(int v);



virtual int calcolaValore()=0;



};



#endif // GIOCATORE_h





file Difensore.h



#ifndef DIFENSORE_H

#define DIFENSORE_H



#include "Giocatore.h"



class Difensore: public Giocatore{

public:

int calcolaValore(){ return v;}

};

#endif // DIFENSORE_H





In pratica ho creato la classe Giocatore come classe astratta e ho messo come metodo virtuale puro calcolaValore() che ho poi definito nella classe Difensore che eredita Giocatore.

Il mio dubbio è va bene questa scelta?

L'ereditarietà è public?

AnonimoVeneziano
03-02-2016, 02:49
Sto svolgendo un esercizio in C++ per la programmazione orientata agli oggetti.

Traccia:
Un giocatore ha nome, età e un valore che dipende dal ruolo del giocatore e dall'età.
Progettare la classe Giocatore fornendo solo la definizione (Giocatore.h) tenendo presente che il sistema deve essere flessibile all'aggiunta di un nuovo ruolo.
Inserire nella classe Giocatore tutti i metodi che si ritengono opportuni motivandone l'aggiunta.

Ho risolto cosi':
file Giocatore.h

#ifndef GIOCATORE_h
#define GIOCATORE_H

class Giocatore{

protected:
string nome;
int eta;
int valore;

public:
string getNome() const;
int getEta() const;
int getValore() const;

void setNome(string n);
void setEta(int e);
void setValore(int v);

int calcolaValore()=0;

};

#endif // GIOCATORE_h


file Difensore.h

#ifndef DIFENSORE_H
#define DIFENSORE_H

#include "Giocatore.h"

class Difensore: public Giocatore{
public:
int calcolaValore(){ return v;}
};
#endif // DIFENSORE_H


In pratica ho creato la classe Giocatore come classe astratta e ho messo come metodo virtuale puro calcolaValore() che ho poi definito nella classe Difensore che eredita Giocatore.
Il mio dubbio è va bene questa scelta?
L'ereditarietà è public?

Onestamente io non creerei mai un nuovo tipo e userei un metodo virtuale per fare una cosa del genere ...

Detto questo pero' questo e' un esercizio ... a volte bisogna capire anche cosa l'esercizio vuole che tu faccia.
Se credi che nella risoluzione tu debba almeno usare una funzione virtuale e creare almeno una classe derivata allora la tua soluzione puo' tenere (anche se mi pare che il valore dipenda solo dal ruolo e non dal ruolo e l'eta') .

Detto questo se e' cosi' e' un esercizio del cappero

mistergks
03-02-2016, 05:52
È un esercizio per verificare l'uso del polimorfismo ed ereditarietà...
Ovviamente la funzione calcolaValore è virtual... Avevo dimenticato di mettere virtual

Il valore c'è scritto che dipende dal ruolo e dall'età ma non è richiesto il calcolo.

Comunque l'ho fatto così ad un esame universitario e sono stato bocciato.
Per questo sto chiedendo qui

marco.r
03-02-2016, 11:30
Mi verrebbe da dire che un Difensore non e' un Giocatore (anche se colloquialmente lo e'), ma un Ruolo di un Giocatore.

Quindi secondo me Giocatore non dovrebbe avere metodi virtuali, ma contenere un oggetto di Tipo ruolo (che sara' poi specializzato in Difensore, Centrocampista etc) a cui delega il calcolo del valore.

mistergks
03-02-2016, 23:47
Un oggetto di tipo ruolo cioè un enum ruolo?

mistergks
06-02-2016, 20:16
Up

marco.r
07-02-2016, 14:57
Un oggetto di tipo ruolo cioè un enum ruolo?

Pensavo ad un oggetto di tipo ruolo, non un enum, ad esempio



#ifndef GIOCATORE_h
#define GIOCATORE_H

class Giocatore{

private:
string nome;
int eta;
int valore;
Ruolo* ruolo;

public:
string getNome() const;
int getEta() const;
int getValore() const;

void setNome(string n);
void setEta(int e);
void setValore(int v);

int calcolaValore();

};

#endif // GIOCATORE_h

#ifndef RUOLO_h
#define RUOLO_h
#ifndef GIOCATORE_h
#define GIOCATORE_H

class Ruolo{

public:
virtual int calcolaValore(int eta)=0;

};

#endif


.........

class Difensore: public Ruolo {
........
};


Qualcosa del genere. il calcolaValore del giocatore usa quello del ruolo. Non tanto migliore della soluzione iniziale ma un po' piu' pulito (ti permette un domani di estendere il comportamento del giocatore anche in base ad altri fattori che non siano il ruolo), e rispetta la richiesta di utilizzare l'ereditarieta'.