2 Bases du langage C++ Le C++ est un langage de programmation permettant la programmation sous de multiples paradigmes comme, par exemple la programmation procédurale (héritée du langage C), la programmation orientée objet (voir le Chapitre 4) et la programmation générique (voir le Chapitre 5). Depuis 1995 environ, C++ est le langage le plus utilisé au monde. Avant d aborder des notions plus complexes, ce chapitre se concentre sur les bases du C++, en plus de celles héritées du langage C.
32 CHAPITRE 2 Bases du langage C++ Hello world en C++ #include <iostream> int main(int argc, char* argv[]) { std::cout << Hello world! << std::endl; return 0; } Voici le pendant C++ du traditionnel HelloWorld du langage C, que nous avons vu dans le chapitre précédent. Notez que par habitude, l extension du fichier n est plus «.c» mais «.cpp» (on rencontre aussi «.cxx» ou encore «.C» surtout sous Unix et GNU-Linux, qui distinguent minuscules et majuscules dans les noms de fichiers). Pour les fichiers d en-têtes C++, la STL (bibliothèque standard du C++) a simplement supprimé l extension (plus de «.h») ; mais aujourd hui, l extension standard est «.hpp» (que l on retrouve dans la bibliothèque BOOST). Si vous avez réussi à compiler ce programme en C, vous y parviendrez sans difficulté en C++. En revanche, il ne faut plus invoquer gcc mais g++. Les mots-clés Voici les listes des mots réservés du C++ qui ne sont pas déjà présents dans le langage C. Elles vous seront utiles pour retrouver facilement leur définition. Pourquoi deux listes et pas une seule? J ai intentionnellement mis à part les nouveaux mots-clés introduits par la norme C++11 afin de mieux les repérer.
Les mots-clés 33 Les mots-clés du C++ Mot-clé Page Mot-clé Page bool 38 protected 78 catch 120 public 40 class 73 reinterpret_cast 47 const_cast 46 static_cast 44 delete 26 template 132 dynamic_cast 48 this 81 explicit 85 throw 148 false 38 true 38 friend 80 try 20 inline 57 typeid 27 mutable 71 typename 22 namespace 52 using 53 new 26 virtual 101 operator 52 wchar_t 41 private 78 Les mots-clés du C++11 Mot-clé Page Mot-clé Page alignas 144 decltype 41 alignof 144 noexcept 163 auto 41 nullptr 61 char16_t 210 static_assert 327 char32_t 210 thread_local 153 constexpr 35
34 CHAPITRE 2 Bases du langage C++ Les constantes Une constante est une valeur qui ne change pas au cours de l exécution d un programme. Une constante ressemble à une macro par différents aspects : sa portée est réduite au fichier où elle est déclarée ; les expressions l utilisant sont évaluées à la compilation ; elle peut être utilisée pour définir la taille d un tableau de type C. Toutefois, contrairement aux macros, le compilateur peut allouer un emplacement mémoire où stocker la constante lorsque cela est requis. C est par exemple le cas lorsque l on utilise son adresse : const int constante_entiere = 345; const int *ptr_sur_constante = &constante_entiere; Si les macros C #define sont toujours disponibles, il est préférable d utiliser le concept de constantes qu offre le C++. Cela permet une vérification de type à la compilation et diminue le risque d erreur. const int a = 2; int const b = 7; // équivalent à la ligne précédente const Objet unobjet; // un objet peut être une constante const int const c = 7; // ERREUR : const dupliqué const double d; // ERREUR : initialisation manquant Pour les pointeurs, le qualificatif const peut aussi bien s appli quer au pointeur qu à l élément pointé : const int entier1; int* ptr = &entier1; // ERREUR : conversion invalide // Pointeur sur une constante const int *a = &constante_entiere; int const *b = &constante_entiere; // équivalent
Les mots-clés 35 // à la ligne précédente a = &constante_entiere; *a = 4; // ERREUR : on ne modifie pas une constante // Pointeur constant sur une variable int *const c = &entier; int *const c; // ERREUR : initialisation manquante c = &entier1; // ERREUR : on ne modifie pas une constante *c = 5; // Pointeur constant sur une constante const int *const d = &constante_entiere; int const *const e = &constante_entiere; // équivalent // à la ligne précédente const int *const f; // ERREUR : initialisation manquante d = &entier1; // ERREUR : on ne modifie pas une constante *d = 5; // ERREUR : on ne modifie pas une constante C++11 : constexpr (expressions constantes généralisées) Le C++ dispose déjà du concept d expression constante. C est le cas par exemple de 3 + 4, qui correspond toujours au même résultat. Les expressions constantes sont des opportunités d optimisation pour le compilateur. Il exécute l expression à la compilation et stocke le résultat dans le programme. D un autre côté, il existe un certain nombre de cas où les spécifications du langage C++ requièrent des expressions constantes : définir un tableau nécessite une constante, et une valeur d énumération doit en être une. Pourtant, alors qu une expression constante est toujours le résultat d un appel de fonction ou d un constructeur, il est impossible actuellement d écrire le code ci-après, parce que cinq() + 5 n est pas une expression constante. Le compilateur n a aucun moyen de savoir que cinq() est une constante. int cinq() { return 5; } int tableau[cinq() + 5]; // illégal C++11 introduit le mot-clé constexpr, qui permet au programmeur de signifier qu une fonction ou un objet est une constante
36 CHAPITRE 2 Bases du langage C++ à la compilation. L exemple précédent peut être réécrit comme ci-après. Cela permet au compilateur de comprendre et vérifier que cinq() est une constante. constexpr int cinq() { return 5; } int tableau[cinq() + 5]; // ok : crée un tableau de 10 entiers L utilisation de constexpr sur une fonction impose à cette dernière des limitations très strictes. Premièrement, la fonction ne peut pas retourner void. Deuxièmement, son contenu doit être de la forme return expression. Troisièmement, expression doit être une expression constante, après substitution des paramètres, qui ne peut qu appeler d autres fonctions définies comme constexpr, ou utiliser d autres variables ou données constantes elles aussi. Quatrièmement, toute forme de récursion est interdite. Enfin, une fonction ainsi déclarée ne peut être appelée que dans sa portée. Les variables peuvent aussi être des expressions constantes. Ainsi déclarées, elles sont implicitement const. Elles peuvent uniquement stocker des résultats d expressions ou de constructeurs constants. constexpr double graviteterrestre = 9.8; constexpr double gravitelunaire = graviteterrestre / 6; Afin de pouvoir créer des objets constants, un constructeur peut être déclaré constexpr. Dans ce cas, son corps doit être vide et ses membres initialisés avec des expressions constantes. Le destructeur d un tel objet doit également être trivial. Tout membre d une classe, comme le constructeur par copie, la surcharge d opérateur, etc., peut être déclaré comme constexpr, à condition qu il vérifie les contraintes d une fonction constante. Cela permet au compilateur de copier des classes ou de faire des opérations sur celles-ci pendant le processus de compilation. Bien entendu, les fonctions et constructeurs constants peuvent être appelés avec des variables non constantes. Dans ce cas, aucune optimisation ne sera faite à la compilation : le code sera appelé lors de l exécution. Du coup, le résultat ne peut évidemment pas être stocké dans une variable constante.
Déclarations de variables 37 Déclarations de variables En C++, la déclaration de variables est considérée comme une instruction. Il n est pas nécessaire de regrouper toutes les déclarations de variables en début de bloc comme en C. int a; int b = 0; Objet o; // déclaration d une variable // déclaration et initialisation // déclaration et appel du constructeur Attention La déclaration de variables peut entraîner l exécution de beaucoup de code, notamment lors de l initialisation des objets (classes). Une variable déclarée dans une boucle for implique que sa portée reste limitée à cette dernière : for (int i=0 ; i<n ; ++i) // for (int i=k ; i>=0 ; --k) // Attention Certains vieux compilateurs C++, comme Visual C++ 6, ne gèrent pas cette spécificité et transforment toute déclaration normalement locale à la boucle for en une déclaration précédant celle-ci. Ainsi, le code ci-dessus ne compilerait pas avec un tel compilateur : un message d erreur prétextant que la variable i est déjà déclarée serait généré pour la deuxième boucle.
38 CHAPITRE 2 Bases du langage C++ Pour vous assurer qu une variable a une portée limitée à un fichier, utilisez un espace de nom anonyme plutôt que de recourir au mot-clé static : static int n; namespace { int n; } // correcte mais de style C // on préférera le style C++ L utilisation de static pour une déclaration variable dans un bloc a le même effet qu en C : l initialisation n a lieu qu une fois et son comportement est semblable à celui d une variable globale uniquement visible dans ce bloc. int f(int x) { static int a = x; return a; } int main(void) { cout << f(10) << endl ; cout << f(12) << endl ; } Produira la sortie suivante : 10 10 Les types de variables spécifiques au C++ bool Le type bool accepte deux états : true (vrai) : correspond à la valeur 1 ; false (faux) : correspond à la valeur 0.
Les types de variables spécifiques au C++ 39 Ce type est codé sur le même nombre de bits que le type int. Lorsque l on convertit un type numéraire en bool, toute valeur non nulle est considérée comme true. bool vrai = true; bool faux = false; Les références Une référence est une sorte de pointeur masqué. Pour décla rer un pointeur, il suffit de rajouter un et commercial (&) après le type : si T est un type, le type référence sur T est T&. int a = 3; int& r = a ; // r est une référence sur a Il est obligatoire d initialiser une référence lors de sa déclaration, sinon vous obtiendrez un message d erreur. En effet, r = b; ne transformera pas r en une référence sur b mais copiera la valeur de b dans r. Astuce Les références permettent de définir des raccourcis (ou alias) sur des objets. int& element = tableau[indice]; element = entier; est équivalent à : tableau[indice] = entier;