Puisque std::list
et std::vector
existe, y a-t-il une raison d'utiliser des tableaux C traditionnels en C++, ou faut-il les éviter, tout comme malloc
?
En C++ 11 où std::array
est disponible, la réponse est "oui, les tableaux doivent être évités". Avant C++ 11, vous devrez peut-être utiliser des tableaux C pour allouer des tableaux dans le stockage automatique (c'est-à-dire sur la pile).
Certainement, bien qu'avec std::array
en C++ 11, pratiquement uniquement pour les données statiques. Les tableaux de style C présentent trois avantages importants par rapport à std::vector
:
Ils ne nécessitent pas d'allocation dynamique. Pour cette raison, les tableaux de style C sont à privilégier lorsque vous avez probablement beaucoup de très petits tableaux. Dites quelque chose comme un point à n dimensions:
template <typename T, int dims>
class Point
{
T myData[dims];
// ...
};
En règle générale, on pourrait imaginer que dims
sera très petit (2 ou 3), T
un type intégré (double
), et que vous pourriez vous retrouver avec std::vector<Point>
avec des millions d'éléments. Vous ne voulez certainement pas des millions d'allocations dynamiques de 3 doubles.
L'initialisation statique du support. Ce n'est qu'un problème pour les données statiques, où quelque chose comme:
struct Data { int i; char const* s; };
Data const ourData[] =
{
{ 1, "one" },
{ 2, "two" },
// ...
};
C'est souvent préférable à l'utilisation d'un vecteur (et std::string
), car cela évite tous ordre des problèmes d'initialisation; les données sont préchargées, avant que tout code réel puisse être exécuté.
Enfin, en relation avec ce qui précède, le compilateur peut calculer la taille réelle du tableau à partir des initialiseurs. Vous n'avez pas à les compter.
Si vous avez accès à C++ 11, std::array
résout les deux premiers problèmes et devrait certainement être utilisé de préférence aux tableaux de style C dans le premier cas. Il ne traite pas du troisième, cependant, et ayant la dimension du compilateur le tableau en fonction du nombre d'initialiseurs est toujours une raison valable pour préférer les tableaux de style C.
Ne dites jamais "jamais", mais je conviens que leur rôle est considérablement diminué par les véritables structures de données de STL.
Je dirais également que l'encapsulation à l'intérieur des objets devrait minimiser l'impact de choix comme celui-ci. Si le tableau est un membre de données privées, vous pouvez l'échanger dans ou hors sans affecter les clients de votre classe.
J'ai travaillé sur des systèmes critiques pour la sécurité où vous ne pouvez pas utiliser l'allocation dynamique de mémoire. La mémoire doit toujours être sur la pile. Par conséquent, dans ce cas, vous utiliserez des tableaux car la taille est fixée au moment de la compilation.
array
dans c++
vous offre une alternative rapide de taille fixe à la taille dynamique std::vector
et std::list
. std :: array est l'un des ajouts dans c++11
. Il offre l'avantage des conteneurs std tout en fournissant la sémantique de type agrégé des tableaux de style C.
Donc, dans c++11
j'utiliserais certainement std::array
, là où c'est requis, sur le vecteur. Mais je voudrais éviter le tableau de style C dans C++03
.
Je sais que beaucoup de gens indiquent std :: array pour l'allocation de tableaux sur la pile et std :: vector pour le tas. Mais aucun ne semble prendre en charge l'alignement non natif. Si vous utilisez tout type de code numérique que vous souhaitez utiliser SSE ou VPX (nécessitant ainsi un alignement de 128 ou 256 octets respectivement), les tableaux C semblent toujours être votre meilleur pari.
Le plus souvent, non, je ne vois pas de raison d'utiliser des tableaux bruts sur, disons, vectors
. Si le code est nouveau .
Vous devrez peut-être recourir à des tableaux si vos bibliothèques doivent être compatibles avec du code qui attend des tableaux et des pointeurs bruts.
Je dirais que les tableaux sont toujours utiles, si vous stockez une petite quantité statique de données, pourquoi pas.
Les tableaux de style C sont une structure de données fondamentale, il y aura donc des cas où il est préférable de l'utiliser. Pour le cas général, cependant, utilisez les structures de données plus avancées qui arrondissent les coins des données sous-jacentes. C++ vous permet de faire des choses très intéressantes et utiles avec la mémoire, dont beaucoup fonctionnent avec des tableaux simples.
Le seul avantage d'un tableau (bien sûr enveloppé dans quelque chose qui gérera automatiquement sa désallocation en cas de besoin) sur std::vector
Je pense que vector
ne peut pas transmettre la propriété de ses données, sauf si votre compilateur prend en charge C++ 11 et déplace les constructeurs.
Vous devez utiliser des conteneurs STL en interne, mais vous ne devez pas passer de pointeurs vers de tels conteneurs entre différents modules, ou vous vous retrouverez dans un enfer de dépendance. Exemple:
std::string foo;
// fill foo with stuff
myExternalOutputProc(foo.c_str());
est une très bonne solution mais pas
std::string foo;
// fill foo with stuff
myExternalOutputProc(&foo);
La raison en est que std :: string peut être implémenté de différentes manières mais une chaîne de style c est toujours une chaîne de style c.