Je viens de commencer à apprendre le C ++ et j’ai une question à propos des vecteurs. Le livre que je lis indique que si je veux extraire la taille d’un vecteur de type double (par exemple), je devrais faire quelque chose comme:
vector::size_type vector_size; vector_size = myVector.size();
Alors qu’en Java je pourrais faire
int vector_size; vector_size = myVector.size();
Ma question est la suivante: pourquoi existe-t-il un type nommé vector :: size_type? Pourquoi le C ++ n’utilise-t-il pas simplement int?
C ++ est un langage d’écriture de bibliothèque *, et permettre à l’auteur d’être aussi général que possible est l’un de ses principaux atouts. Plutôt que de demander aux conteneurs standard d’utiliser un type de données particulier, l’approche plus générale consiste à size_type
que chaque conteneur expose un type de membre size_type
. Cela permet une plus grande flexibilité et généricité. Par exemple, considérons ce code générique:
template Container, typename T> void doStuff(const Container & c) { typename Container ::size_type n = c.size(); // ... }
Ce code fonctionnera sur n’importe quel modèle de conteneur (pouvant être instancié avec un seul argument), et nous n’imposons aucune ressortingction inutile à l’utilisateur de notre code.
(En pratique, la plupart des types de taille seront résolus en std::size_t
, qui est à son tour un type non signé, généralement unsigned int
ou unsigned long
– mais pourquoi devrions-nous savoir cela?)
*) Je ne suis pas sûr de ce que serait la déclaration correspondante pour Java.
Java n’a pas de types entiers non signés, ils doivent donc aller avec int
.
Au contraire, C ++ les utilise et les utilise le cas échéant (où les valeurs négatives sont insensées), l’exemple canonique étant la longueur de quelque chose comme un tableau.
La norme C ++ dit que size_type
un conteneur est un type intégral non signé, mais elle ne spécifie pas lequel; une mise en œuvre peut utiliser unsigned int
et une autre peut utiliser unsigned long
, par exemple.
C ++ n’est pas “protégé” des détails d’implémentation spécifiques à la plate-forme autant que Java. L’alias size_type
aide à protéger votre code de tels détails. Il fonctionnera donc correctement quel que soit le type utilisé pour représenter la taille d’un vecteur.
Mon sentiment personnel à ce sujet est que c’est pour une meilleure sécurité / lisibilité du code.
Pour moi, int
est un type qui n’a aucune signification particulière: il peut numéroter des pommes, des bananes ou n’importe quoi.
size_type
, qui est probablement un typedef
pour size_t
a un sens plus fort: il indique une taille, en octets.
C’est-à-dire qu’il est plus facile de savoir ce que signifie une variable. Bien entendu, en suivant cette logique, il pourrait y avoir beaucoup de types différents pour différentes unités. Mais une “taille de mémoire tampon” est vraiment un cas courant, elle mérite donc en quelque sorte un type dédié.
La maintenabilité du code est un autre aspect: si le conteneur change soudainement son size_type
par exemple, uint64_t
en unsigned int
par exemple, en utilisant size_type
vous n’avez pas à le changer dans chaque code source qui en size_type
.
Le livre que vous lisez indique que si vous souhaitez extraire la taille d’un vecteur de type double (par exemple), vous devez procéder comme suit:
vector::size_type vector_size; vector_size = myVector.size();
Alors qu’en Java, vous pourriez faire
int vector_size; vector_size = myVector.size();
Les deux sont des options inférieures en C ++. Le premier est extrêmement verbeux et dangereux (principalement en raison de promotions implicites). La seconde est verbeuse et extrêmement dangereuse (en raison de la plage de nombres).
En C ++, faites
ptrdiff_t const vectorSize = myVector.size();
Notez que
ptrdiff_t
, à partir de l’en stddef.h
tête stddef.h
, est un type signé qui est garanti suffisamment grand.
L’initialisation est faite dans la déclaration (c’est un meilleur style C ++).
La même convention d’appellation a été appliquée aux deux variables.
En résumé, faire le bon choix est plus court et plus sûr.
Vive & hth.,