Creare array di oggetti in c++ crea sempre qualche problema nella gestione della memoria e nella chiamata ai costruttori.
Infatti una definizione del tipo
Oggetto array[100];
creerà un array di puntatori a 100 oggetti del tipo Oggetto
richiamando per ciascuno di essi il costruttore senza parametri. Questo non è sempre corretto. Un’alternativa sarebbe definire l’array come array di puntatori, come di seguito:
Oggetto *array[100]
Questa istruzione creerà un array di puntatori a aree di memoria non inizializzate con nessun oggetto. Con un ciclo si dovranno poi costruire gli oggetti a uno a uno.
Questo schema prevede una gestione della memoria manuale, con il rischio di leak di memoria.
Le nuove specifiche richiedono di utilizzare i contenitori standard, in particolare std::vector
. Questo contenitore richiede un po’ di gestione in più, con i relativi costruttori di copie e gli operatori move
.
Ovviamente si potrà usare un’istruzione del tipo:
std::vector<Oggetto> array;
creando poi i vari oggetti a uno a uno. In alternativa si può usare un contenitore di puntatori, facendo attenzione che siano puntatori smart.
Suggerimenti per evitare in modo sicuro perdite di memoria
Piuttosto che utilizzare un std::vector
di puntatori nudi, utilizzare una raccolta di oggetti std::unique_ptr
://THIS CREATES VECTOR
std::vector<std::unique_ptr<combustion_car>> combustion_car_list;
- Creare l’oggetto temporaneo utilizzando una chiamata a
std::make_unique
e trasferirne la proprietà al contenitore utilizzandostd::move
://THIS IS CREATING AND PUSHING THE OBJECT
std::unique_ptr<combustion_car> temporary=std::make_unique<combustion_car>(); temporary->create();
combustion_car_list.push_back(std::move(temporary));
std::cout<<"Object added"<<std::endl;
- Rimuovere l’elemento in
combustion_car_list[choice] (choice-1
non è corretto, ma anche pericoloso perché potrebbe produrre un valore dell’iteratore che è precedente )combustion_car_list.begin()
;//THIS DELETES OBJECT FROM VECTOR combustion_car_list.erase(combustion_car_list.begin() + choice);