PDA

Visualizza la versione completa : [c++]problemi d'ereditarietà


cleaner
27-12-2008, 15:40
ciao a tutti,
ci tengo a precisare che il progetto è molto più grande, ma per farvi capire(essendo impossibilitato a postare tt il code) ho riassunto il problema in un esempio:

main.cpp


#include <iostream>
#include "classe1.h"
#include "classe2.h"
using namespace std;

int main()
{
x prova1;
y prova2;
prova1.creazionefile();
prova2.dati();

return 0;
}



classe1.h


#include <iostream>
#include <fstream>
using namespace std;

class x
{
public:
string aprifile;
void creazionefile()
{
cin >> aprifile;
aprifile=aprifile+".txt";
fstream nuovofile;
nuovofile.open(aprifile.c_str(),ios::out);
nuovofile << "Prima riga" <<endl;
nuovofile.close();
}

};



classe2.h


#include <iostream>
#include <fstream>

using namespace std;

class y : public x
{
public:
void dati()
{
fstream dato(aprifile.c_str(),ios::out|ios::app);
if(!dato)
{
cout << "Apertura non riuscita";
}
dato << "Seconda riga";
dato.close();
}
};



se compilate potrete notare che di problemi non ne da, tuttavia non fa il suo dovere in quanto si solleva l'eccezione di non riuscita dell'apertura del file(classe2).
A grandi linee è questo il problema..non mi spiego come sia possibile in quanto la classe è derivata e il dato nella classe base è di tipo public.
grazie

Xaratroom
27-12-2008, 17:13
non hai assegnato un valore alla stringa, utilizzata nell'istanza prova2:


#include <iostream>
#include "classe1.h"
#include "classe2.h"
using namespace std;

int main()
{
x prova1;
y prova2;
prova1.creazionefile();
prova2.dati();

return 0;
}

dovrebbe essere:


#include <iostream>
#include "classe1.h"
#include "classe2.h"
using namespace std;

int main()
{
y prova2;
prova2.creazionefile();
prova2.dati();

return 0;
}

YuYevon
27-12-2008, 17:22
Guarda direi che c'è un errore concettuale: nel metodo dati() della classe derivata y tu accedi ad un valore inesistente di aprifile. Mi spiego:

il nome del file lo associ al valore aprifile dell'oggetto prova1, ma l'oggetto prova2 non ha alcun valore per l'attributo aprifile, quindi quando col metodo dati() provi ad aprire il file che hai definito in precedenza, il metodo accede al valore nullo dell'attributo aprifile dello stesso oggetto e giustamente viene lanciata l'eccezione di apertura falilta. Puoi modificare così:



void dati( string nome_file )
{
fstream dato(nome_file.c_str(),ios::out|ios::app);
if(!dato)
{
cout << "Apertura non riuscita";
}
dato << "Seconda riga";
dato.close();
}


e la chiamata nel main



prova2.dati( prova1.aprifile )

cleaner
27-12-2008, 20:37
mm..scusami ma sto facendo un po di confusione, non è un argomento molto facile :master:
allora, da quanto ho capito io, una classe derivata eredita dalla classe base tutti i membri_dato e i metodi associati ad essa.
Come mi hai descritto te la situazione però eredita si i membri ma non il loro valore quindi?
Ma l'utilizzo di quel parametro "prova1.aprifile"
nel richiamo di prova2.dati( prova1.aprifile ) non è indispensabile se io uso direttamente la classe derivata per fare tutto vero?
grazie, se ho fatto confusione ditemelo che cerco di spiegarmi meglio.

YuYevon
27-12-2008, 22:51
Sì, se usi direttamente la classe derivata per fare tutto hai la soluzione che ti ha proposto Xaratroom prima di me, che va bene. Nel caso però volessi conservare l'ereditarietà devi ricorrere ad una soluzione tipo quella che ti ho postato io...



Come mi hai descritto te la situazione però eredita si i membri ma non il loro valore quindi?

Sì esatto, l'errore consisteva nell'aver confuso le classi (che sono quelle coinvolte nell'ereditarietà) con gli oggetti, che sono solo intanze delle classi.

Quando chiami il metodo creazionefile() su prova1 (oggetto di classe x) vai ad associare al suo attributo aprifile un certo valore. Dopo utilizzi il metodo dati() su prova2, che è un altro oggetto, la cui classe ha ereditato da x attributi e metodi public ma questo non significa che l'oggetto prova2 erediti i valori degli attributi di prova1. Infatti se all'interno del metodo dati() provi a stampare aprifile (col tuo programma di prima, senza la modifica) ti ritroverai con un valore nullo, questo perché non hai mai assegnato nulla all'attributo aprifile di prova2, ma solo a quello di prova1.

L'ereditarietà coinvolge gli schemi delle classi, non le loro particolari istanze (oggetti).

cleaner
28-12-2008, 11:07
perfetto ti ringrazio :ciauz:

Loading