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_uniquee trasferirne la proprietà al contenitore utilizzandostd::move://THIS IS CREATING AND PUSHING THE OBJECTstd::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-1non è 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);