|
| HOMEPAGE | INDICE FORUM | REGOLAMENTO | ::. | NEI PREFERITI | .:: | RSS Forum | RSS News | NEWS web | NEWS software | |
| PUBBLICITA' | | | ARTICOLI | WIN XP | VISTA | WIN 7 | REGISTRI | SOFTWARE | MANUALI | RECENSIONI | LINUX | HUMOR | HARDWARE | DOWNLOAD | | | CERCA nel FORUM » | |
02-09-2009, 15.02.06 | #1 |
Newbie
Registrato: 24-08-2009
Messaggi: 4
|
[C++] Lista di struct
sto lavorando ad un progetto con linguaggio c++. Mi è stato chiesto di implementare un template lista basato su un template elemento di lista utilizzando 2 campi generici e i vari puntatori che servono per implementare le liste. Poi dovrei utilizzare il template lista per costruire una biblioteca. in questa biblioteca si utlizza la struct Infovolume con vari campi che danno informazioni sul volume. Quindi credo che debba implementare una lista di struct Infovolume per costruire la classe biblioteca. Ecco la domanda è: è possibile usare le funzioni base della lista oppure devo ricostruire ogni funzione per la nuova classe biblioteca? Cioè ad esempio: per inserire il nome del volume, devo richiamare la funzione inserisci del template lista oppure costruirne un'altra nella classe biblioteca? e se si, che tipo di sintassi bisogna usare? Scusate le domande ma sul manuale ho semplici esempi di classi che utilizzano come tipo di dato nel template un dato semplice come intero oppure striung. Non so come comportarmi con liste di struct. Grazie mille Codice:
//dichiarazione del template elemento di lista template<class gen> class List_element { public: gen data; gen key; List_element<gen> *succ; List_element<gen> *prec; List_element(); ~List_element(); void set_element(gen a,gen b); gen get_element(); List_element *get_next(); void set_next(List_element *p); List_element *get_prev(); void set_prev(List_element *s); //dichiarazione del template lista bidirezionale template <class gen> class lista_concatenata_bidirezionale { public: List_element<gen>* TestaDiLista; List_element<gen>* CodaDiLista; int num_elementi; lista_concatenata_bidirezionale(); ~lista_concatenata_bidirezionale(); void Crea_lista(); bool Lista_vuota(); List_element<gen>* ultimo_lista(); gen leggi(List_element<gen>*p); void scrivi(List_element<gen>*p, gen a,gen b); void cancella(List_element<gen>*p); void inserisci(List_element<gen>*p, gen a,gen b); int getNumElementi(); List_element<gen>* cerca(gen a); void Stampa_lista(); List_element<gen>* succ_lista(List_element<gen>* pos); }; //dichiarazione di Infovolume struct Infovolume { string nome; string disposizione; int disponibilita'; } //dichiarazione di Biblioteca class Biblioteca { lista_concatenata_bidirezionale<Infovolume> biblioteca; ....................................................... ............................................................ .......................................................... }; |
02-09-2009, 16.53.12 | #2 |
Gold Member
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
|
Se la lista è specializzata (ovvero non opera con tipi nativi) e devi reimplementare il suo template occorre specializzare anche i metodi che consento di : inserire (push_back) cancellare (remove, removeat opzionale) e iterare (iteratore) poiché operino con l'oggetto struttura o con l'operatore di cui hai bisogno
guarda qui per l'implementazione standard di una lista http://www.ziggyware.com/readarticle.php?article_id=20 prendi spunto da questo esempio e reimplementa il tuo template poiché sia in grado di operare con la struct di cui hai bisogno, reimplementa soltanto i metodi che ti servono dopodiché usala come una normale lista Codice:
listtemplate <InfoVolume> myList ... Ultima modifica di P8257 WebMaster : 02-09-2009 alle ore 17.24.21 |
03-09-2009, 19.24.38 | #3 |
Newbie
Registrato: 24-08-2009
Messaggi: 4
|
Ciao WebMaster e grazie per il consiglio. In realtà ho già implementato sia il template lista che il template elemento di lista come nell'esempio.
Il problema è che non riesco ad operare sui singoli campi della struct utilizzando le funzioni base che operano su tipi generici implementate nei template. cioè come faccio ad aggiornare ad esempio la quantità di un libro con le sole operazioni definite nel template? |
03-09-2009, 23.24.11 | #4 |
Gold Member
WT Expert
Registrato: 09-01-2002
Loc.: None of your business
Messaggi: 5.505
|
Codice semplice per i semplici concetti fondamentali...
Funzioni generiche Codice:
/* swapargs è una funzione generica alla quale vengono passati due parametri di tipo X. X non ha nulla a che vedere con la classe. Ad X verrà assegnata la tipologia del dato nel momento in cui verrà invocata la funzione swapargs. */ template <class X> void swapargs(X &a, X &b){ /* A swapargs vengono passati gli indirizzi di a e b il cui valore dipenderà dal tipo del dato specificato al momento della compilazione del codice. */ X temp; // temp è una variabile temporanea di tipo X. // Il tipo di dato referente ad a e b sarà specificato // al momento della chiamata alla funzione swapargs. temp = a; a = b; b = temp; cout << "\nvalore di parametro1:" << a << " valore di prametro2:" << b << "\n"; }; int main(void){ // swapargs è sempre la stessa funzione, ma il tipo del parametro cambia. int i=10; int j=20; cout << "valore di parametro1:" << i << " valore di parametro2:" << j; swapargs(i,j); char c='a'; char d='b'; cout << "valore di parametro1:" << c << " valore di parametro2:" << d; swapargs(c,d); return 0; } Codice:
/* MyClass è una classe generica alla quale vengono passati due parametri di tipo X. X non ha nulla a che vedere con la classe. Ad X verrà assegnata la tipologia del dato nel momento in cui verrà creato il costruttore di MyClass. */ template <class X> class MyClass{ X x,y; //x ed y sono due variabili private generiche di tipo X public: // Costruttore della classe MyClass MyClass(X a, X b){ // a e b sono due variabili generiche di tipo X x = a; y = b; } // div() è una funzione generica della classe MyClass di tipo X X div(){ return x/y; } }; int main(void){ /* d_ob è una classe generica che eredita da MyClass membri e funzioni il cui tipo è specificato all atto del creazione del costruttore della classe */ MyClass<double> d_ob(10.0, 3.0); cout << "divisione di double: " << d_ob.div(); /* i_ob è una classe generica che eredita da MyClass membri e funzioni il cui tipo è specificato all atto del creazione del costruttore della classe */ MyClass<int> i_ob(10, 3); cout << "\ndivisione di interi: " << i_ob.div(); return 0; } Codice:
/* MyClass è una classe generica alla quale vengono passati due parametri di tipo X. X non ha nulla a che vedere con la classe. Ad X verrà assegnata la tipologia del dato nel momento in cui verrà creato il costruttore di MyClass. */ template <class X> class MyClass{ X x,y; //x ed y sono due variabili private generiche di tipo X public: // Costruttore della classe generica MyClass MyClass(X a, X b){ // a e b sono due variabili generiche di tipo X x = a; y = b; } // div() è una funzione generica della classe MyClass di tipo X X div(){ return x/y; } }; // I parametri passati a MyClass vengono definiti in modo specifico, template <> class MyClass<int>{ int x, y; // x ed y sono due variabili private all'interno della classe public: // Costruttore della classe specifica MyClass MyClass(int a,int b){ x = a; y = b; } // div() è una funzione della classe MyClass di tipo intero. int div(){ return x/y; } }; int main(void){ /* d_ob è una classe generica che eredita da MyClass membri e funzioni il cui tipo è specificato all atto del creazione del costruttore della classe */ MyClass<double> d_ob(10.0, 3.0); cout << "divisione di double: " << d_ob.div(); /* i_ob è una classe generica che eredita da MyClass membri e funzioni il cui tipo è specificato all atto del creazione del costruttore della classe */ MyClass<int> i_ob(10, 3); cout << "\ndivisione di interi: " << i_ob.div(); return 0; } |
04-09-2009, 00.12.21 | #5 |
Gold Member
WT Expert
Registrato: 09-01-2002
Loc.: None of your business
Messaggi: 5.505
|
Ok, ora abbiamo gettato le basi per cominciare a comprendere la classe List http://www.cplusplus.com/reference/stl/list/
|
04-09-2009, 10.24.40 | #6 |
Gold Member
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
|
Non sono sicuro di aver capito bene il problema dell'operare coi campi, forse perché stai cercando di operare con una lista despecializzata su un contesto specializzato...
Oltre ai link e agli spunti che ti ha fornito Lory volevo suggerirti di guardare nuovamente il link dell'implementazione standard ed in particolare... Codice:
void push_back(T Item) { bValid=false; if(m_pEnd) { m_pEnd->m_pNext = new ListNode(Item); m_pEnd->m_pNext->m_pPrev = m_pEnd; m_pEnd = m_pEnd->m_pNext; } else { m_pHead = new ListNode(Item); m_pEnd = m_pHead; } m_dwSize++; } void Insert(T Item,ListNode* pPrev = 0) { bValid=false; m_dwSize++; if(!pPrev) { ListNode* pBase = m_pHead; m_pHead = new ListNode(Item); m_pHead->m_pNext = pBase; if(!pBase) pBase = m_pHead; pBase->m_pPrev = m_pHead; if(!m_pEnd) { m_pEnd = pBase; } } else { ListNode* pNext = pPrev->m_pNext; if(!pNext) { pPrev->m_pNext = new ListNode(Item); pPrev->m_pNext->m_pPrev = pPrev; if(m_pEnd == pPrev) { m_pEnd = pPrev->m_pNext; } } else { pPrev->m_pNext = new ListNode(Item); pPrev->m_pNext->m_pPrev = pPrev; pPrev->m_pNext->m_pNext = pNext; pNext->m_pPrev = pPrev->m_pNext; if(m_pEnd == pPrev) { m_pEnd = pPrev->m_pNext; } } } } |
06-09-2009, 12.10.55 | #7 |
Gold Member
WT Expert
Registrato: 09-01-2002
Loc.: None of your business
Messaggi: 5.505
|
Abbiamo visto che l'operatore new viene utilizzato per allocare ed eventualmente popolare un array di qualsiasi tipo attraverso l'utilizzo di un puntatore alla memoria dinamica (heap).
La classe generica list, utilizzabile attraverso l'inclusione dell'header <list.h> (#include <list>), fa ampio uso di template e di strutture che puntano a loro stesse, in modo tale da creare un array espandibile (dinamico) di oggetti. Il link da me proposto, mostra come utilizzare la classe list in modo da creare un array di interi, ma non è molto chiaro su come gestire un array di strutture. Una struttura è anch'essa un tipo di dato, così come lo sono int e char (persino una classe), ma può essere costituita da differenti tipi di dato, nonchè funzioni inline. Facciamo un esempio semplice e chiaro: 1 - Creiamo la struttura MiaStruct1 struct MiaStruct1{ char x; int y; }; 2 - Creiamo ora una classe list di tipo MiaStruct1 list<MiaStruct1> L1; 3 - Identifichiamo un puntatore alla struttura MiaStruct1 MiaStruct1 *p; 4 - Utilizziamo la classe L1 per allocare un array dinamico di 3 elementi di tipo MiaStruct1 p=L1.get_allocator().allocate(3); p ora punta ad una lista concatenata di tre elementi di struttura MiaStruct1 5 - Popoliamo ogni elemento dell'array. p[0].x='A' ; p[0].y=1 ; p[1].x='B' ; p[1].y=2 ; p[2].x='C' ; p[2].y=3 ; 6 - Visualizziamo ogni elemento dell'array for(int i=0; i<3; i++) cout << p[i].x << p[i].y << endl; 7 - Infine deallochiamo la memoria dinamica allocata in precedenza. L1.get_allocator().deallocate(p,3); Vediamo ora un ulteriore esempio di utilizzo della classe facendo riferimento ai membri pubblici esplicitamente predisposti, al fine di ottenere un approccio più C++ alla classe list. Facciamo un esempio semplice e chiaro: 1 - Creiamo la struttura MiaStruct2 struct MiaStruct2{ char x_; int y_; MiaStruct2(char x, int y) : x_(x), y_(y) { }; }; In questo caso, MiaStruct2 diventa una sorta di costruttore inline di se stessa che contiene al suo interno il prototipo. si potrà popolare MiaStruct2 chiamandola direttamente ed assegnando ad x_ il valore di x ed ad y_ il valore di y. 2 - Creiamo ora una classe list di tipo MiaStruct2 list<MiaStruct2> L2; 4 - Utilizziamo la classe L2 per allocare un array dinamico di 3 elementi di tipo MiaStruct2 L2.push_back(MiaStruct2('a',1)); L2.push_back(MiaStruct2('b',2)); L2.push_back(MiaStruct2('c',3)); 5 - Ora è necessario implementare un puntatore ad ogni elemento dell'array, in modo da poter iterare su ogni elemento di cui si compone l'insieme. list<MiaStruct2>::iterator it2; 6 - Visualizziamo ogni elemento dell'array for(it2=L2.begin(); it2!=L2.end(); it2++) cout << (*it2).x_ << (*it2).y_ << endl; In ultimo, il programma completo: Codice:
struct MiaStruct1{ char x; int y; }; struct MiaStruct2{ char x_; int y_; MiaStruct2(char x, int y) : x_(x), y_(y) { }; }; main(void){ list<MiaStruct1> L1; MiaStruct1 *p; p=L1.get_allocator().allocate(3); p[0].x='A' ; p[0].y=1 ; p[1].x='B' ; p[1].y=2 ; p[2].x='C' ; p[2].y=3 ; for(int i=0; i<3; i++) cout << p[i].x << p[i].y << endl; L1.get_allocator().deallocate(p,3); list<MiaStruct2> L2; L2.push_back(MiaStruct2('a',1)); L2.push_back(MiaStruct2('b',2)); L2.push_back(MiaStruct2('c',3)); list<MiaStruct2>::iterator it2; for(it2=L2.begin(); it2!=L2.end(); it2++) cout << (*it2).x_ << (*it2).y_ << endl; } |
07-09-2009, 10.17.02 | #8 |
Gold Member
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
|
(Y)...
|
Utenti attualmente attivi che stanno leggendo questa discussione: 1 (0 utenti e 1 ospiti) | |
Strumenti discussione | |
|
|
Discussioni simili | ||||
Discussione | Autore discussione | Forum | Risposte | Ultimo messaggio |
vedere lista contatti in gmail con accanto indirizzo x esteso... | cippico | Software applicativo | 1 | 25-06-2009 08.50.12 |
Lista dei file caricati sulle periferiche virtuali | monroo | Software applicativo | 1 | 17-06-2007 11.52.45 |
Lista nera linee aeree | Flying Luka | Archivio News Web | 29 | 30-08-2005 16.15.51 |
CANCELLAZIONE LISTA NUOVO CARTELLA/COLLEGAMENTO w98/me | anton | Windows 9x/Me/NT4/2000 | 1 | 05-05-2004 15.01.13 |
Excel 2000: problema lista file recenti | damiano | Office suite | 0 | 31-01-2004 14.23.20 |