Newsgroup: it.comp.lang.c++
Titolo: [LUNGHETTO] Come fare?

Salve a tutti,
avrei un piccolo problema:
ho del vecchio codice scritto per funzionare con una certa struttura X che
serve per leggere dati da un file. Adesso il programma e' stato aggiornato e
ho dovuto ingrandire con nuovi campi tale struttura. Adesso quindi potrei
tranquillamente crearmi 2 puntatori a tali strutture ed in base alla
versione del file che sto per leggere utilizzare o uno o l'altro...purtroppo
pero' dovrei cambiare tutto il codice e mettere un 'if' per ogni lettura e
ci vorrebbe davvero un lavoro lungo (e sporco).
Ho pensato di creare la nuova struttura ereditandola da quella vecchia ed
aggiungendo tutti i nuovi campi...tutto sembra funzionare e infatti riporto
i due codici (vecchio e nuovo):
VECCHIO:
VecchiaStrutt *point;
/* codice che utilizza point per leggere dal file */
NUOVO
struct NuovaStrutt : VecchiaStrutt {
    //** campi nuovi
};
NuovaStrutt *point;
if(Versione)
    point= new NuovaStrutt [2];  //nuova versione del file
else
    point= new VecchiaStrutt [2]; //vecchia versione del file
/* vecchio codice che utilizza point per leggere dal file */
tutto sembra funzionare bene a parte il fatto che quando istanzio una
struttura vecchia (quella base) e voglio fare point[x].Campo mi fa una
violazione di accesso (giustamente perche' fa point + x*sizeof(NuovaStrutt )
e non point + x*sizeof(VecchiaStrutt) come vorrei). Potrei risolvere il
problema con ((VecchiaStrutt *)point)[x]) ma mi ritroverei la stessa
situazione di dover mettere un if per ogni volta che uso il puntatore. Come
fare per risolvere sto' problema?
Grazie per l'attenzione



Ehm, ammetto di aver capito davvero poco... Cosa intendi per 'usare la
vecchia struttura' ? Il problema dipende largamente da come la
utilizzi...
Saluti,
	Marco Palestro

| Ehm, ammetto di aver capito davvero poco... Cosa intendi per 'usare la
| vecchia struttura' ? Il problema dipende largamente da come la
| utilizzi...
Il codice e' molto simile a questo:
PS: la VecchiaStruttura e' quella base mentre la nuova e' derivata dalla
vecchia come ho scritto nel post precedente
/* leggo header del file */
NuovaStruct *point;
if(iVersioneHeader == 0)
{
      (VecchiaStruct *) point = new VecchiaStruct[x];
      iSize = sizeof(VecchiaStruct);
}
else if(iVersioneHeader == 1)
{
       point = new NuovaStruct[x];
       iSize = sizeof(NuovaStruct);
}
il mio problema e' che adesso se uso una istruzione del tipo:
point[1]
io accedo alla locazione:
point + sizeof(NuovaStruct)
che va bene nel caso di iVersioneHeader == 1 mentre va male nel caso di
iVersioneHeader == 0 perche' in tal caso io vorrei accedere alla locazione .
point + sizeof(VecchiaStruct)
La soluzione al problema e' quello di utilizzare
((VecchiaStruct *)point)[1]  ma in tal caso dovrei cambiare tutto il codice
di tutto il programma per inserire un if condizionatamente al fatto che mi
trovo con una versione 0 o una versione 1.
Spero che stavolta sia stato un po' piu' chiaro :)
Ciao

 dati derivata...
Questo sarebbe l'unico inconveniente se si trattasse di un singolo oggetto.
Max

| impressione e' che sia impossibile. L'unica soluzione e' quella di
| implementare le funzioni di lettura nella struttura dati, cosi' da
| ricorrere alle funzioni virtuali.
infatti penso che alla fine sara' questa l'unica soluzione :(
| P.S. A me sembra che non ci siano problemi nell'usare point[1]; il
| riferimento viene tradotto automaticamente alla locazione giusta, no ?
no...il problema che il puntatore e' pur sempre un puntatore alla struttura
derivata.
Quando invece lo voglio utilizzare come puntatore alla struttura base va
bene per quanto riguarda l'accesso agli elementi della struttura (tanto
nella classe derivata ci sono tutti gli elementi della base piu' qualcun
altro) ma funziona 'male' per quanto riguarda l'uso di point[1] perche'
point e' pur sempre un puntatore alla classe derivata e quindi avanza di
sizeof(ClasseDerivata).
Ma nientemeno non esiste nessun modo per fare questo? se ad esempio avessi
un puntatore a void e nel corso del programma volessi farlo diventare
puntatore ad int facendo il cast una volta per tutte, non e' possibile?
boh...
Grazie delle risposte

| No. Se assegni il puntatore ad un *array* di oggetti di classe derivata ad
| un puntatore a classe base stai evidentemente cercando rogne. E'
| un'operazione che non ha alcun senso, perché non è possibile usare il
| puntatore per scorrere l'array, se non facendo un cast al tipo appropriato
| (ma a questo punto, tanto vale usare un void*).
scusa, e come potrebbe risolversi il problema?
ok, utilizzo un puntatore a void.
void *p;
da un altra parte io voglio utlizzare p ma non so che cast fare perche'
questa informazione varia in funzione del file che sto per leggere quindi e'
dinamica...devo per forza implementare delle ruotine di lettura-scrittura
oppure in ogni zona del programma che usa p[i] usare la notazione:
if(versione == 0)
    ((Base *)p)[i];
else
    p[i]
davvero non c'e' altro modo??
Ciao

 appropriato (ma a questo punto, tanto vale usare un void*).
Perche' no ? Certo, non devo usare un puntatore alla classe derivata; si
usa sempre un puntatore alla classe base, e in tal caso l'indirizzamento
ha successo. Resta naturalmente il problema di fare il casting quando si
vuole accedere ai dati della classe derivata.
Il codice:
NuovaStruct *point;
if(iVersioneHeader == 0)
{
      (VecchiaStruct *) point = new VecchiaStruct[x]; iSize =
      sizeof(VecchiaStruct);
}
else if(iVersioneHeader == 1)
{
       point = new NuovaStruct[x];
       iSize = sizeof(NuovaStruct);
}
puo' (o forse quantomeno dovrebbe) essere sostituito da:
VecchiaStruct *point;
if(iVersioneHeader == 0)
{
      point = new VecchiaStruct[x];
      iSize = sizeof(VecchiaStruct);
}
else if(iVersioneHeader == 1)
{
       point = new NuovaStruct[x];
       iSize = sizeof(NuovaStruct);
}
o sbaglio ? Siccome ero in dubbio ho fatto una breve prova, e non ho
trovato nessun problema a riferirmi ai vari elementi del vettore, sia che
si riferisca ad elementi di classe base che derivata. Dov'e' l'errore ?


 
Oops, non funziona davvero... ehm ^_^;


 ha scritto nel messaggio
news:XW0Fa.16283$Fr5.3...@tornado.fastwebnet.it...

Scusa.. ma se invece di usare un array normale ti crei una tua classe Array?
Sicuramente potresti effettuare dei controlli sul tipo e regolarti di
conseguenza sull'elemento che devi farti restituire e l'esatta collocazione
di questo in memoria!
L'if sarebbe solo1, o cmq sarebbero pohci.. e facilmente individuabili..
Quindi la soluzione nn mi sembrerebbe sporca..
Sxo d'averti aiutato.. Ciaooo
PS: E' tanto che nn programmo in C++ ;P


Ti suggerirei volentieri qualcosa, ma ho non abbastanza elementi. Ho la
sensazione che tu cerchi di trovare una soluzione *locale* a un
inconveniente quando invece dovresti rivedere leggermente l'approccio.
Come usi i due tipi di struct? Che ruolo svolgono nelle operazioni di
lettura-scrittura? Non potresti creare due classi diverse, derivate dalla
stessa base polimorfica, che si occupino della lettura-scrittura delle due
versioni del file rispettivamente, e che internamente usino l'una o l'altra
delle due famose struct?
Max