View Full Version : [C++] Creare oggetti dinamicamente
Ciao a tutti, ho bisogno di un consiglio:
Ho creato una classe città nella quale inserire i dati di una data città inserita dall'utente, il problema è che vorrei che venisse creato un oggetto città a run time.
Ho fatto un menu con switch e in pratica ogni volta che premo 1 vorrei che si creasse un oggetto in cui poter modificare i dati.. come posso fare?
Ho visto che si può implementare tramite liste e puntatori o con <vector>, però penso di dover mettere gli oggetti in un array visto che dovrei farci ricerche e modifiche.. spero di essere stato chiaro, grazie :D
[Kendall]
26-05-2012, 15:22
Ciao a tutti, ho bisogno di un consiglio:
Ho creato una classe città nella quale inserire i dati di una data città inserita dall'utente, il problema è che vorrei che venisse creato un oggetto città a run time.
Ho fatto un menu con switch e in pratica ogni volta che premo 1 vorrei che si creasse un oggetto in cui poter modificare i dati.. come posso fare?
Ho visto che si può implementare tramite liste e puntatori o con <vector>, però penso di dover mettere gli oggetti in un array visto che dovrei farci ricerche e modifiche.. spero di essere stato chiaro, grazie :D
Devi crearti un contenitore di puntatori a città. Se come contenitore stai su di un array ricorda però che sarà di dimensione fissa, se invece utilizzi un vector potrai aumentarne la dimensione dinamicamente. Fatto questo, nel case dello switch relativo al tasto 1 devi inserire una istanziazione dinamica. In pratica ti prendi uno dei puntatori del tuo container e ne associ una istanza dinamica dell'oggetto città.
Detta in c++_ese fai una cosa del tipo:
contenitore[i] = new Città( /* lista parametri */ );
Grazie della risposta, però sto cercando di capire come fare un contenitore di puntatori a città, mettiamo caso che usi gli array (purtroppo con i vector non ho mai visto niente) per fare un array di puntatori ad oggetti non mi basta scrivere questo?
citta* puntcitta = new citta[100]
Il mio "contenitore" a questo punto dovrebbe essere l'array città[100], giusto? Però facendo così il compilatore da errore ('new' cannot appear in constant expression, iso c++ forbids initialization of member puntcitta, making puntcitta static)
Ho visto alcuni esempi e viene creato un puntatore a un puntatore ad array di oggetti, però non capisco il perché si debba utilizzare un "doppio" puntatore..
Grazie
AllerITA
26-05-2012, 20:01
Se usi Visual Studio 2010 può esserti utile la seguente spiegazione per instanziare un array di classi:
http://msdn.microsoft.com/en-us/library/fs4s9exz.aspx
e soprattutto questa:
http://msdn.microsoft.com/en-us/library/kewsb8ba.aspx
Che dice chiaramente che gli array di oggetti sono semplicemente allocabili con
il metodo che hai descritto se la classe degli oggetti ha un costruttore di default:
cioè se la classe ha un costruttore senza parametri.
Altrimenti devi creare un array di puntatori alla classe che popolerai a mano uno per uno:
Citta *puntatori[100];
puntatori[i]=new Citta(\*lista parametri costruttore*\);
Correggetemi se sbaglio.
[Kendall]
27-05-2012, 01:36
Grazie della risposta, però sto cercando di capire come fare un contenitore di puntatori a città, mettiamo caso che usi gli array (purtroppo con i vector non ho mai visto niente) per fare un array di puntatori ad oggetti non mi basta scrivere questo?
citta* puntcitta = new citta[100]
Il mio "contenitore" a questo punto dovrebbe essere l'array città[100], giusto? Però facendo così il compilatore da errore ('new' cannot appear in constant expression, iso c++ forbids initialization of member puntcitta, making puntcitta static)
Ho visto alcuni esempi e viene creato un puntatore a un puntatore ad array di oggetti, però non capisco il perché si debba utilizzare un "doppio" puntatore..
Grazie
Perchè quello che dichiari tu è un array di oggetti città, e ne assegni la prima posizione al puntatore puntcittà. A questo punto tu hai già allocato 200 istanze di città, usando il suo costruttore di default.
Quello del quale hai bisogno tu è un array di puntatori a città, cioè una cosa così:
citta **cities = new citta*[20];
oppure
citta *cities[20];
Per aggiungere città poi ti basterà fare così:
cities[0] = new citta(....);
cities[1] = new citta(....);
cities[2] = new citta(....);
ecc....
Se usi Visual Studio 2010 può esserti utile la seguente spiegazione per instanziare un array di classi:
http://msdn.microsoft.com/en-us/library/fs4s9exz.aspx
e soprattutto questa:
http://msdn.microsoft.com/en-us/library/kewsb8ba.aspx
Che dice chiaramente che gli array di oggetti sono semplicemente allocabili con
il metodo che hai descritto se la classe degli oggetti ha un costruttore di default:
cioè se la classe ha un costruttore senza parametri.
Altrimenti devi creare un array di puntatori alla classe che popolerai a mano uno per uno:
Citta *puntatori[100];
puntatori[i]=new Citta(\*lista parametri costruttore*\);
Correggetemi se sbaglio.
Non ho aperto i link, ma direi che la tua spiegazione è assolutamente corretta. Unica precisazione da far notare è che istanziando direttamente un array di puntatori dovrai specificare la grandezza a compile-time, mentre con il puntatore a puntatore di città puoi specificarla a runtime (in quanto poi istanzi l'array dinamicamente).
AllerITA
27-05-2012, 07:01
Si hai ragione ho fatto un errore mi sono un po perso il titolo del topic.:doh:
[Kendall]
27-05-2012, 14:20
Si hai ragione ho fatto un errore mi sono un po perso il titolo del topic.:doh:
No beh mica hai scritto qualcosa di errato, anzi, semplicemente è diverso. Uno è più flessibile ma richiede maggiori attenzioni nella deallocazione, mentre l'altro è più "sicuro", più performante ma richiede di ipotizzare prima la grandezza del vettore di puntatori, cosa che potrebbe non essere sempre ovvia.
Grazie mille :D
L'unica implementazione che non mi da errore è citta* cities[100], con quella a doppio puntatore mi da gli stessi errori che ho scritto sopra (e infatti è come avevo provato), adesso ho fatto una funzione void creaCitta() in cui uso l'indice per avanzare nell'array ogni volta che creo un nuovo oggetto solamente che dal main non riesco a richiamarla.. nel senso, io ho sempre fatto esercizi in cui si creava l'oggetto nel main (es. citta c1) e poi si richiamava la funzione per ogni oggetto in questo modo: c1.creaCitta();
Qui però non avendo un oggetto specifico già creato ma volendolo creare a run time, come faccio a richiamare la funzione senza che mi dia errore? Se scrivo semplicemente creaCitta() non sa con che oggetto usarla :mbe:
Grazie!
AllerITA
28-05-2012, 07:50
Basta che la funzione non sia implementata come metodo della classe cosi:
#include <stdio.h>
//include altri header del progetto
CreaCitta(Citta**cites,int indice);
int main()
{
Citta *city[100];
int i;
i=0;
//inizializza vettore city[100] es; for(int j=0; j<100; j++,city[j]=NULL);
//Codice
CreaCitta(city,1);
//Codice
CreaCitta(city,i);
//Codice
//Cancella elementi vettore city es for(int j=0; j<100; j++)
//{ if (NULL !=city[j]) {delete city[j];city[j]=NULL;};}
//Codice
return 0;
}
CreaCitta(Citta * * cities,int indice)
{
//codice
cities[indice]=new Citta(/*lista parametri*/);
//codice
}
[Kendall]
28-05-2012, 08:16
Grazie mille :D
L'unica implementazione che non mi da errore è citta* cities[100], con quella a doppio puntatore mi da gli stessi errori che ho scritto sopra (e infatti è come avevo provato), adesso ho fatto una funzione void creaCitta() in cui uso l'indice per avanzare nell'array ogni volta che creo un nuovo oggetto solamente che dal main non riesco a richiamarla.. nel senso, io ho sempre fatto esercizi in cui si creava l'oggetto nel main (es. citta c1) e poi si richiamava la funzione per ogni oggetto in questo modo: c1.creaCitta();
Qui però non avendo un oggetto specifico già creato ma volendolo creare a run time, come faccio a richiamare la funzione senza che mi dia errore? Se scrivo semplicemente creaCitta() non sa con che oggetto usarla :mbe:
Grazie!
Fidati che deve funzionare, probabilmente non hai scritto precisamente come ti avevo suggerito.
p.s: in una situazione del genere comunque io ti consiglio di utilizzare una "map" come contenitore. Non avendo particolari motivi per avere le città in ordine ti tornerebbe utile l'associazione key -> value della map, associando alla key "nome città" il value "oggetto città". Questo ti permetterebbe successivamente di poter accedere alle tue città facendo una ricerca per nome, senza dover scorrere tu manualmente l'array. Poi ovviamente dipende tutto dalle necessità che hai nel programma, perchè se necessiti invece di un sistema più flessibile e complesso, con la possibilità per esempio di ordinare le città per numero di abitanti o altro, allora forse è meglio incapsulare il tutto dentro una classe contenitore fatta da te, nella quale implementi a mano la ricerca per nome, i vari algoritmi di ordinamento e tutte le altre funzionalità delle quale necessiti. (E' proprio questo lo spirito della programmazione ad oggetti)
Ok ce l'ho fatta, grazie :D Un'altra cosa e poi non vi rompo più, adesso che riesco a creare l'oggetto città ogni volta che premo 1 nello switch vorrei associare la funzione inserisciCitta() che ho nella classe con l'oggetto appena creato nell'array, però ho errore di compilazione.. se invece creo il solito oggetto citta c1 nel main nessun problema.. perchè? :muro:
Grazie ancora!
AllerITA
29-05-2012, 08:05
ricorda che il vettore arrayCitta[] è un array di puntatori, quindi puoi richiamare un suo metodo con il seguente operatore sui puntatori:
arrayCitta[j]->inserisciCitta();
che in parole povere e' come fare:
(*(arrayCitta[j])).inserisciCitta();
poi mi e' venuto in mente che la funzione creaCitta(citta ** cities,int indice);
puo' essere aggiunta come metodo statico della classe citta.
se la dichiari static puoi sempre richiamarla così
nel programma ad es:
citta::creaCitta(citta ** cities,int indice);
ricordati solo che dentro un metodo statico non puoi mettere nessuna variabile di istanza (se non è anch'essa statica) altrimenti ti da un errore.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.