PDA

Visualizza la versione completa : [C++] Liste di oggetti ed ereditarietà classi


folal
06-02-2011, 17:56
Salve,
sono alle primissime armi con lo studio del C++ e mi ritrovo con un problema banale x chi sicuramente di C++ ne sa molto più di me.

Per esercizio, mi trovo a gestire una lista di elettrodomestici, la cui struttura fornita è la seguente: oggetto elettrodomestico(tipo, consumo)
|
ogg.lavatrice; ogg.lavastoviglie; ogg.frigorifero

la lista l'ho pensata in questo modo, cioè un insime di nodi:

struct listElem {
elettrodomestico elm_elettrod;
struct listElem* next;
};
typedef struct listElem* lista;

In input viene richiesto il tipo di elettrodomestico che si sta inserendo, ed a seconda
della scelta istanzio un oggetto di tipo diverso (lavatrice, lavastoviglie, frigorifero....), che
specializza l'oggetto elettrodomestico che costituisce il nodo.

Il mio problema è come istanziare un nodo della lista, che definisce l'oggetto elettrodomestico
ed attribuirgli un oggetto specializzato (lavatrice, lavastoviglie, frigorifero....)....

Spero di essere stato chiaro e spero che qualcuno mi aiuti.
Grazie.

lolide
06-02-2011, 18:13
Uhm ma hai intenzione di usare C++ o usi il C ?
Se vuoi usare il C++, usa gli oggetti.

C++ - OOP (http://programmazione.html.it/guide/lezione/1151/la-programmazione-ad-oggetti/)

Se vuoi conoscere il tipo dell'elettrodomestico fai una classe Elettrodomestico, lo fai ereditare da Lavatrice, Lavastoviglie eccc... e usando gli enum puoi creare un attributo tipoElettrodomestico che farai overridare da ogni subclasse, settato con il tipo elettrodomestico.



typedef enum { LAVATRICE, LAVASTOVIGLIE } TipoElettrodomestico;
class Elettrodomestico {
public:
virtual TipoElettrodomestico getTipo() = 0;
....
};

class Lavastoviglie : virtual public Elettrodomestico {
public:
TipoElettrodomestico getTipo () {
return TipoElettrodomestico.LAVASTOVIGLIE;
};
};


questo è un esempio, ovviamente Elettrodomestico è una classe astratta (anche tu sai il perchè ;))

folal
06-02-2011, 18:29
A dire il vero, la classe elettrodomestico nn l'avevo pensata astratta,
in quanto credovo di mettere al suo interno i parametri: tipo elettrodom. ; consumo; prezzo.
Parametri che mi servono poi per la ricerca.

Ma se mi dici che sia meglio in altro modo, sono tutto orecchi! :smack:

Come seconda cosa, come faccio a istanziare il nodo della lista ed attribuirgli
l'oggetto lavatrice oppure lavastoviglie, uppure frigorifero.....?

Mi potresti fare un esempio?

Grazie.

lolide
06-02-2011, 18:46
Originariamente inviato da folal
A dire il vero, la classe elettrodomestico nn l'avevo pensata astratta,
in quanto credovo di mettere al suo interno i parametri: tipo elettrodom. ; consumo; prezzo.
Parametri che mi servono poi per la ricerca.

Ma se mi dici che sia meglio in altro modo, sono tutto orecchi!

Io ragionando ad oggetti ho pensato: "Esiste un elettrodomestico che si chiami elettrodomestico ?" :)

Cioè l'elettrodomestico è un oggetto astratto, ha dei metodi come tipo elettrodomestico, consumo, prezzo, dimensioni ecc... che sono comuni agli elettrodomestici ma un'entità elettrodomestico non esiste in se' per se'


Originariamente inviato da folal
Come seconda cosa, come faccio a istanziare il nodo della lista ed attribuirgli
l'oggetto lavatrice oppure lavastoviglie, uppure frigorifero.....?

Mi potresti fare un esempio?

Grazie.

Per questo fatto della lista dobbiamo ragionarci sopra: è giusto secondo te mettere un puntatore ad un Elettrodomestico nella classe Elettrodomestico ?
Cioè Elettrodomestico è un oggetto unico.

Secondo me è meglio costruire un'altra classe ListaElettrodomestici che conterrà oggetti Elettrodomestico.



Elettrodomestico *e = (Elettrodomestico*)new Lavastoviglie();
e->getTipo(); //TipoElettrodomestico.LAVASTOVIGLIE

folal
06-02-2011, 18:55
OK...
effettivamente il tuo ragionamento non fa una piega, di fatto l'oggetto
elettrodomestico non esiste in raeltà, ma una sua rappresentazione specifica(lavatrice, ...).

Detto questo faccio una classe astratta elettrodomestico, in cui xò metto
gli attributi: tipo, consumo e prezzo; giusto?

Faccio un paio di prove in base all'esempio che mi hai girato relativo all'istanzazione del
nodo della lista.


Grazie. :smack:

folal
08-02-2011, 12:08
Aiuto, ....
sono ancora alle prese nel cercare di impostare una corretta tassonomia degli oggetti,
ma nn mi compila nulla e credo che il tutto derivi da un pò di confusione che ho in testa!

Parto con il primo problema/domanda:

se dichiaro il nodo per la gestione della lista elettrodomestici, come segue:

struct listElem {
elettrodomestico* elm_elettrod;
struct listElem* next;
};
typedef struct listElem* lista;

se elettrodomestico è un'iterfaccia pura, da cui deriva lavatrice, lavastoviglie.... posso far puntare
elettrodomestico* elm_elettrod a ciascun tipo di oggetto reale, lavatirce, lavastoviglie....?

shodan
08-02-2011, 12:30
Puoi farlo solo tramite un cast. Però se hai progettato bene l'interfaccia, non dovrebbe nemmeno servire.
Tra l'altro l'implementazione della lista la devi fare tu o puoi usare anche altro? Tipo la STL?

folal
08-02-2011, 14:33
Scusatemi,
ma potreste mica farmi un esempio di codice,
tenendo conto che mi trovo a gestire una tassonomia di questo genere:

Elettrodomestico.h
class elettrodomestico{
protected:
string tipo; //lavatrice, aspirapolvere....
int energia_Kw; //consumo
int prezzo;
public:
elettrodomestico();
~elettrodomestico();
string getTipo();
int getConsumo();
int getPrezzo();
};
*************************************
Elettrodomestico.cpp
elettrodomestico::elettrodomestico() {
tipo = //vorrei che venisse assegnato in basa all'oggetto specifico di elettrodomestico
cout << "consumo (Kw): ";
cin >> energia_Kw;
cout << "prezzo: ";
cin >> prezzo;
};

elettrodomestico::~elettrodomestico() {
printf("elettrodomestico-distruttore su\t%p\n",this);
};

string elettrodomestico::getTipo(){
return tipo;
}
int elettrodomestico::getConsumo(){
return energia_Kw;
}
int elettrodomestico::getPrezzo(){
return prezzo;
}
****************************************
Lavatrice.h
class lavatrice:public elettrodomestico{
bool lava_asciuga; //(si,no)
string carico; //dall'alto(A), basso(B)
public:
lavatrice();
~lavatrice();
string getTipo(){return tipo;}
int getConsumo(){return energia_Kw;}
int getPrezzo(){return prezzo;}
};
****************************************
Lavatrice.cpp
avatrice::lavatrice() {
cout << "lava e asciuga(S/N): ";
cin >> lava_asciuga;
cout << "carico(A/B): ";
cin >> carico;
};

lavatrice::~lavatrice() {
printf("lavatrice-distruttore su\t%p\n",this);
};
****************************************
Lista.cpp
struct listElem {
elettrodomestico* elm_elettrod;
struct listElem* next;
};
typedef struct listElem* lista;

Questo è quello che ho impostato come classi, ma nn è corretto!!!

shodan
08-02-2011, 18:21
Puoi partire da qualcosa come questo.


// Interfaccia pura astratta
class Elettrodomestico {
public:
elettrodomestico(){};
virtual ~elettrodomestico(){};
virtual string getTipo() const=0;
virtual int getConsumo() const=0;
virtual int getPrezzo()cont= 0;
};
// Classe dedicata allo storage dei dati.
class ElettrodomesticoDataType : public Elettrodomestico {
protected:
string tipo; //lavatrice, aspirapolvere....
int energia_Kw; //consumo
int prezzo;
};
// Classe concreta di implementazione.
class Lavatrice : public ElettrodomesticoDataType {
public:
Lavatrice() {const int& consumo, const int& prz) {
tipo = "Lavatrice";
energia_Kw = consumo;
prezzo = prz;
}
~Lavatrice() {}
string getTipo() const { return tipo; }
int getConsumo() const { return energia_Kw; }
int getPrezzo() const { return prezzo; }
};

typedef std::shared_ptr<Elettrodomestico> SPElettrodomestico;

int main (void) {
std::vector<SPElettrodomestico> Elettrodomestici;
Elettrodomestici.push_back(SPElettrodomestico(new Lavatrice(250, 3000)));

cout << Elettrodomestici[0]->getTipo() << "; ";
cout << Elettrodomestici[0]->getConsumo() << "; ";
cout << Elettrodomestici[0]->getPrezzo() << endl;
}

lolide
08-02-2011, 20:05
Originariamente inviato da folal
****************************************
Lista.cpp
struct listElem {
elettrodomestico* elm_elettrod;
struct listElem* next;
};
typedef struct listElem* lista;

Questo è quello che ho impostato come classi, ma nn è corretto!!!

Intanto la classe Elettrodomestico perchè non l'hai lasciata virtual ? è sbagliato dal punto di vista della programmazione ad oggetti ma cmq non da problemi.

Quella lista NON E' AD OGGETTI!
E' una struct del C, perchè ti ostini ad usarle?
Se la lista devi crearla tu da 0 , allora ti consiglio di fare una cosa come questa:


class ListaElettrodomestici {
private:
Elettrodomestico *elettr;
ListaElettrodomestici *next;
};

ed implementare i metodi. Se non capisci cosa possa significare, allora ti consiglio di studiarti le linkedlist, che sono un tipo di lista molto importante dal punto di vista didattico.

Cmq non ho capito bene se hai bisogno per forza di usare una Linkedlist oppure va bene anche un semplice vettore di Elettrodomestici.

Se è così allora segui il consiglio di shodan usando il template std::vector

Loading