Come molte altre domande e risposte già affermate, non vi è alcuna sintassi in C ++ che permetta di dichiarare e riempire una matrice di dimensioni dinamiche con oggetti costruttivi non predefiniti.
Obj* array = new Obj[size];
Qui, se Obj
ha un costruttore predefinito, sarà usato per riempire array
con size
istanze predefinite di Obj
, che è un problema.
Le risposte più ricorrenti a questa domanda menzionano i vettori ( qui ), o il meccanismo utilizzato dai vettori, il nuovo posizionamento ( qui ). Tuttavia, il primo non è un'opzione nel mio caso, e vorrei evitare quest'ultimo perché mi sembra un po 'sporca e disordinata (essere usato da STL forse lo rende un buon modo per fare le cose, ma in realtà sembra disordinato).
Modifica: perché i vettori non sono un'opzione: questo progetto è una sfida su cui voglio mettermi alla prova e voglio mettere le mani nel fango tanto quanto Io posso. Se non si utilizzano i vettori, si intende l'utilizzo delle notizie sul posizionamento come indicato di seguito, quindi è quello che farò.
Mi rendo conto che mi sono lamentato del fatto che le notizie sul posizionamento sono disordinate, e mi rendo conto anche che mettere le mani nel fango significa dover gestire un tale pasticcio.
Un'altra risposta ricorrente è usare le parentesi graffe per riempire l'array con oggetti non predefiniti:
Obj* array = new Obj[2] {Obj(foo), Obj(bar)};
Questo lo rende un array semi-dinamico , se posso dire. Essere allocati sull'heap non lo rende statico, ma la dimensione deve essere una costante in fase di compilazione, quindi non la considererei fully dinamica (o almeno non tanto quanto voglio che sia ).
La soluzione più ovvia per me sarebbe dichiarare l'array come sopra, lasciarlo riempire con oggetti junk e costruiti di default e quindi ri-riempirlo con gli oggetti corretti, come segue:
Obj* array = new Obj[size];
for (int i = 0; i < size; i++)
{
array[i] = Obj(whatever);
}
Tuttavia, le prestazioni sono molto importanti nel mio programma e sono piuttosto preoccupato dell'impatto sulle prestazioni di tali metodi. Se size
è 10000, l'array verrà riempito con 10000 oggetti indesiderati, che potrebbero essere molto costosi nel tempo. Quindi, il costo della sostituzione in seguito potrebbe essere anche peggiore (mentre è ancora possibile ridurre al minimo con un uso efficiente dell'idioma copy-and-swap ), e anche questa è una preoccupazione.
Invece, stavo pensando di usare un doppio malloc
.
Obj** array = malloc(sizeof(Obj*) * size);
for (int i = 0; i < size; i++)
{
array[i] = malloc(sizeof(Obj));
array[i] = new Obj(whatever);
}
//...
for (int i = 0; i < size; i++)
{
delete array[i];
free(array[i]);
}
free(array);
Ma non sembra completamente cache-friendly. E non mi sembra giusto avere una coppia di malloc
(avendo già uno solo non si sente bene).
Quindi ecco la mia domanda: c'è un modo bello e pulito che ti permette di allocare la memoria non inizializzata e poi riempirla con oggetti costruiti su misura, che non degradano le prestazioni?
Modifica: la mia vera domanda è: ci sono altri modi oltre a quelli che ho menzionato sopra?
( P.S.: So che la "memoria non inizializzata" non va bene con RAII, e quindi non va bene con "bello e pulito")