Dal momento std::listche std::vectoresistono, c'è una ragione per usare gli array C tradizionali in C ++, o dovrebbero essere evitati, proprio come malloc?
Dal momento std::listche std::vectoresistono, c'è una ragione per usare gli array C tradizionali in C ++, o dovrebbero essere evitati, proprio come malloc?
Risposte:
In C ++ 11, dove std::arrayè disponibile, la risposta è "sì, gli array dovrebbero essere evitati". Prima di C ++ 11, potrebbe essere necessario utilizzare array C per allocare array nell'archiviazione automatica (cioè nello stack).
Sicuramente, anche se con std::arrayin C ++ 11, praticamente solo per dati statici. Gli array in stile C hanno tre importanti vantaggi rispetto a
std::vector:
Non richiedono allocazione dinamica. Per questo motivo, gli array in stile C sono da preferire dove è probabile che ci siano molti array molto piccoli. Di 'qualcosa come un punto a dimensione n:
template <typename T, int dims>
class Point
{
T myData[dims];
// ...
};
Tipicamente, si potrebbe immaginare un che dimssarà molto piccolo (2 o 3),
Tun tipo incorporato ( double) e che si potrebbe finire
std::vector<Point>con milioni di elementi. Sicuramente non vuoi milioni di allocazioni dinamiche di 3 doppie.
L'inizializzazione statica del supporto. Questo è solo un problema per i dati statici, dove qualcosa come:
struct Data { int i; char const* s; };
Data const ourData[] =
{
{ 1, "one" },
{ 2, "two" },
// ...
};
Questo è spesso preferibile all'utilizzo di un vettore (e std::string), poiché evita tutti i problemi di ordine di inizializzazione; i dati vengono precaricati, prima che qualsiasi codice effettivo possa essere eseguito.
Infine, in relazione a quanto sopra, il compilatore può calcolare la dimensione effettiva dell'array dagli inizializzatori. Non devi contarli.
Se hai accesso a C ++ 11, std::arrayrisolve i primi due problemi e nel primo caso dovrebbe essere sicuramente utilizzato in preferenza agli array in stile C. Non si occupa del terzo, tuttavia, e avere il compilatore che dimensiona l'array in base al numero di inizializzatori è ancora un motivo valido per preferire gli array in stile C.
int i[] = { 1, 2, 3 };continua a lavorare con int i[] = { 1, 2, 3, 4 };. array<int, 3>deve essere modificato manualmente in array<int, 4>.
make_arrayfunzione , simile a make_pairecc. Hat-tip a @R. Martinho Fernandes .
std::arrayin C ++ 11, [dovrebbero essere usati] praticamente solo per dati statici".
Non dire mai "mai", ma sarei d'accordo sul fatto che il loro ruolo è notevolmente ridotto dalle vere strutture di dati da STL.
Direi anche che l'incapsulamento all'interno di oggetti dovrebbe ridurre al minimo l'impatto di scelte come questa. Se l'array è un membro di dati privati, puoi scambiarlo dentro o fuori senza influenzare i client della tua classe.
Ho lavorato su sistemi critici per la sicurezza in cui non è possibile utilizzare l'allocazione dinamica della memoria. La memoria deve essere sempre in pila. Pertanto in questo caso usereste gli array poiché la dimensione è fissata in fase di compilazione.
std::array<T>alloca sugli stack e fondamentalmente non ha overhead su un array grezzo.
arrayin c++ti offre un'alternativa rapida a dimensioni fisse di dimensioni dinamiche std::vectore std::list. std :: array è una delle aggiunte in c++11. Fornisce il vantaggio dei contenitori std pur fornendo la semantica di tipo aggregato degli array in stile C.
Quindi c++11userei sicuramente std::array, dove è richiesto, sul vettore. Ma eviterei l'array in stile C in C++03.
La maggior parte di solito, no , non posso pensare a una ragione per usare le matrici prime sopra, dire vectors. Se il codice è nuovo .
Potrebbe essere necessario ricorrere all'uso di array se le librerie devono essere compatibili con il codice che prevede array e puntatori non elaborati.
vector.data()in C ++ 11 o &vector.front()precedente.
So che molte persone indicano std :: array per l'allocazione di array sullo stack e std :: vector per l'heap. Ma nessuno dei due sembra supportare l'allineamento non nativo. Se stai eseguendo qualsiasi tipo di codice numerico su cui desideri utilizzare le istruzioni SSE o VPX (richiedendo quindi rispettivamente un allineamento di 128 o 256 byte), gli array C sembrerebbero comunque essere la soluzione migliore.
Direi che gli array sono ancora utili, se si memorizza una piccola quantità statica di dati perché no.
L'unico vantaggio di un array (ovviamente avvolto in qualcosa che gestirà automaticamente la sua deallocazione quando necessario) su std::vectorcui posso pensare è che vectornon può passare la proprietà dei suoi dati, a meno che il tuo compilatore non supporti C ++ 11 e muova i costruttori.
swap.
Gli array in stile C sono una struttura dati fondamentale, quindi ci saranno casi in cui è meglio usarli. Per il caso generale, tuttavia, utilizzare le strutture di dati più avanzate che arrotondano gli angoli dei dati sottostanti. Il C ++ ti consente di fare alcune cose molto interessanti e utili con la memoria, molte delle quali funzionano con semplici array.
std::arrays? In molti casi, entrambi verranno compilati nello stesso assembly.
std::arrayha una semantica definita con precisione costruita su array statici.
Dovresti usare internamente i contenitori STL, ma non dovresti passare puntatori a tali contenitori tra diversi moduli, o finirai nell'inferno delle dipendenze. Esempio:
std::string foo;
// fill foo with stuff
myExternalOutputProc(foo.c_str());
è un'ottima soluzione ma non lo è
std::string foo;
// fill foo with stuff
myExternalOutputProc(&foo);
Il motivo è che std :: string può essere implementato in molti modi diversi, ma una stringa in stile c è sempre una stringa in stile c.