103
Programmation orientée objet Philippe Robillard

Elements POO

  • Upload
    phrwav

  • View
    30

  • Download
    0

Embed Size (px)

DESCRIPTION

Syllabus POO (C++)

Citation preview

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 1

    Programmation oriente objet

    Philippe Robillard

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 2

    Tables des matires 1. Conventions d'criture .................................................................................................................................................... 5 2. Avertissements ................................................................................................................................................................ 6 3. Rfrences pour le langage ............................................................................................................................................. 6

    3.1. Sur internet .......................................................................................................................................................... 6 3.2. Fichiers distribus ................................................................................................................................................ 6

    3.2.1. Les livres .................................................................................................................................................. 6 3.2.2. Les supports de cours ............................................................................................................................... 6

    3.3. Bibliographie ....................................................................................................................................................... 6 4. Approche syntaxique du langage C++ ............................................................................................................................ 7

    4.1. Les commentaires ................................................................................................................................................ 7 4.2. Le caractre de continuation ................................................................................................................................ 7 4.3. Lieux de dclarations des variables globales et locales ....................................................................................... 7 4.4. Valeur, pointeur et rfrence ............................................................................................................................... 8

    4.4.1. Particularits des rfrences et de leur usage comparativement aux pointeurs ........................................ 8 4.5. Le qualificatif const ........................................................................................................................................... 10

    4.5.1. Dclaration et initialisation .................................................................................................................... 10 4.5.1.1. Pointeur sur une valeur constante ............................................................................................... 10 4.5.1.2. Pointeur dune valeur constante .................................................................................................. 10 4.5.1.3. Pointeur constant dune valeur quelconque ................................................................................ 11 4.5.1.4. Pointeur constant dune valeur constante .................................................................................... 11 4.5.1.5. Pointeur constant sur une valeur constante ................................................................................. 11 4.5.1.6. Rfrences et constantes ............................................................................................................. 11 4.5.1.7. Tableaux et constantes ................................................................................................................ 11

    4.5.2. Le qualificatif const et les arguments des fonctions ............................................................................... 11 4.6. Les librairies ...................................................................................................................................................... 13 4.7. Les instructions dentres et de sorties standards .............................................................................................. 13

    4.7.1. Quelques manipulateurs de la classe ostream .................................................................................... 14 4.7.2. Quelques manipulateurs de la classe istream .................................................................................... 14 4.7.3. Exemples de saisies diverses .................................................................................................................. 15 4.7.4. Saisie de phrases .................................................................................................................................... 15

    4.7.4.1. Chane stocke dans un vecteur .................................................................................................. 15 4.7.4.2. Chane stocke dans une variable de type string ................................................................... 15

    4.7.5. Caractre invalide dans cin .................................................................................................................. 16 4.8. Conversions de type .......................................................................................................................................... 16 4.9. Les paramtres optionnels ................................................................................................................................. 18 4.10. La fonction inline ............................................................................................................................................ 19 4.11. Le type boolen ............................................................................................................................................... 19 4.12. Le type string.............................................................................................................................................. 20 4.13. Surcharge et redfinition des fonctions ........................................................................................................... 23

    4.13.1. Signature dune fonction ...................................................................................................................... 23 4.13.2. Surcharge dune fonction ..................................................................................................................... 23 4.13.3. Surdfinition dune fonction ................................................................................................................ 24

    4.14. Allocation dynamique de la mmoire .............................................................................................................. 24 4.14.1. Organisation de la mmoire ................................................................................................................. 24 4.14.2. Contrle des erreurs dallocation ......................................................................................................... 25

    5. La programmation oriente objet .................................................................................................................................. 27 5.1. Introduction ....................................................................................................................................................... 27

    5.1.1. Depuis 1960 ........................................................................................................................................... 27 5.1.2. Quelles diffrences ? .............................................................................................................................. 27 5.1.3. Un autre niveau de programmation ........................................................................................................ 28

    5.2. Classe et structure .............................................................................................................................................. 28 5.3. Ecriture dune classe et namespace ................................................................................................................... 29 5.4. Ecriture modulaire des classes et des programmes ........................................................................................... 30

    5.4.1. Mise en uvre sous linterface de dveloppement ................................................................................ 31 5.4.2. La cration dune classe et son intgration dans le projet ...................................................................... 32 5.4.3. Pour conclure la question de lcriture modulaire .................................................................................. 33

    5.5. Une classe bien construite ................................................................................................................................. 33 5.6. Une classe bien crite ........................................................................................................................................ 35

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 3

    5.6.1. Les outils et techniques de la classe bien crite ..................................................................................... 36 5.6.1.1. Constructeurs et destructeur ........................................................................................................ 36

    5.6.1.1.a. Les constructeurs.............................................................................................................. 36 5.6.1.1.b. Le destructeur .................................................................................................................. 38

    5.6.1.2. Loprateur daffectation ............................................................................................................ 39 5.7. Spcificits diverses du C++ en POO ............................................................................................................... 41

    5.7.1. Membres statiques .................................................................................................................................. 42 5.7.1.1. La variable statique dune fonction membre ............................................................................... 42 5.7.1.2. La donne statique membre dune classe .................................................................................... 43 5.7.1.3. La fonction statique membre dune classe .................................................................................. 44

    5.7.2. La "classe statique" ................................................................................................................................ 45 5.7.2.1. La variable statique de type objet ............................................................................................... 45

    5.7.3. Fonctions membres inline ...................................................................................................................... 46 5.7.4. Fonctions membres constantes ............................................................................................................... 46 5.7.5. Initialisation de membres dans les enttes des constructeurs ................................................................. 47 5.7.6. Des objets en arguments et en valeurs de retour des fonctions membres .............................................. 48

    5.7.6.1. Mode de transmissions des objets aux fonctions membres ......................................................... 48 5.7.6.1.a. Transmission par valeur ................................................................................................... 48 5.7.6.1.b. Transmission par pointeur ............................................................................................... 49 5.7.6.1.c. Transmission par rfrence .............................................................................................. 49

    5.7.6.2. Mode de retour dun objet par une fonction membre.................................................................. 50 5.7.7. Les fonctions et classes amies ................................................................................................................ 51

    5.7.7.1. Librairie de fonctions amies indpendantes ................................................................................ 51 5.7.7.2. La classe amie ............................................................................................................................. 53 5.7.7.3. Pour conclure les questions damiti........................................................................................... 54

    5.7.8. La surcharge des oprateurs ................................................................................................................... 55 5.7.8.1. Les deux modes de surcharges des oprateurs ............................................................................ 55

    5.7.8.1.a. Particularits communes .................................................................................................. 55 5.7.8.1.b. Surcharges internes .......................................................................................................... 55 5.7.8.1.c. Surcharge externes ........................................................................................................... 58

    5.7.8.2. Coexistence intra classe de surcharges internes et de surcharges externes ................................. 60 5.7.8.3. Coexistences interclasses de surcharges internes et de surcharges externes ............................... 61 5.7.8.4. Pour conclure la question des coexistences ................................................................................ 62 5.7.8.5. Surcharge interne de loprateur daccs .................................................................................... 66

    5.8. Lhritage .......................................................................................................................................................... 69 5.8.1. La cascade dinstanciations .................................................................................................................... 69 5.8.2. Hritage simple ...................................................................................................................................... 70 5.8.3. Hritage multiple .................................................................................................................................... 71

    5.8.3.1. Garantir lunicit de laeule ....................................................................................................... 73 5.8.4. Particularits de lhritage ...................................................................................................................... 74

    5.8.4.1. Lhritage ne transmet pas tout ................................................................................................... 74 5.8.4.2. Accs aux membres de la classe mre ........................................................................................ 74 5.8.4.3. Contrle du degr de visibilit par le type de drivation ............................................................ 75

    5.8.4.3.a. Drivation prive.............................................................................................................. 76 5.8.4.3.b. Drivation protge .......................................................................................................... 76 5.8.4.3.c. Drivation publique.......................................................................................................... 76

    5.8.4.4. Redfinition de membres de la classe mre ................................................................................ 76 5.8.4.5. Transmission dinformations entre constructeurs lors des instanciations implicites .................. 77 5.8.4.6. Quoi dautre entre classe de base et classe drive ? .................................................................. 78

    5.8.4.6.a. Conversion de type........................................................................................................... 78 5.8.4.6.b. A propos du constructeur par recopie .............................................................................. 78 5.8.4.6.c. A propos de loprateur daffectation .............................................................................. 79 5.8.4.6.d. A propos des surcharges doprateurs ............................................................................. 79

    5.9. Le polymorphisme ............................................................................................................................................. 80 5.9.1. Mthode virtuelle ................................................................................................................................... 80 5.9.2. Classe abstraite et mthode virtuelle pure .............................................................................................. 81

    5.9.2.1. Virtualit du destructeur requise ................................................................................................. 81 5.9.2.2. Mthode virtuelle par dfaut ....................................................................................................... 81 5.9.2.3. Classe abstraite sans mthode virtuelle ....................................................................................... 82

    5.9.3. Exploitation du polymorphisme ............................................................................................................. 83

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 4

    5.9.3.1. Mthodes propres de la classe drive ........................................................................................ 86 5.9.3.2. Mthodes propres de la classe mre ............................................................................................ 86

    5.9.4. Avantages du polymorphisme ................................................................................................................ 88 6. Notions complmentaires en C++ ................................................................................................................................ 89

    6.1. La classe "interface" .......................................................................................................................................... 89 6.2. Les templates ..................................................................................................................................................... 90

    6.2.1. Fonctions gnriques .............................................................................................................................. 90 6.2.2. Classes paramtrables ............................................................................................................................ 92 6.2.3. Les conteneurs de la STL ....................................................................................................................... 93

    Le conteneur "pair" .................................................................................................................................. 94 Le conteneur "vector" .............................................................................................................................. 95 Le conteneur "deque" ............................................................................................................................... 95 Le conteneur "list" ................................................................................................................................... 95 Le conteneur "set" .................................................................................................................................... 96 Le conteneur "map" ................................................................................................................................. 96

    6.3. Les fichiers ........................................................................................................................................................ 97 6.3.1. Le fichier accs direct .......................................................................................................................... 98 6.3.2. Le fichier binaire .................................................................................................................................. 101 6.3.3. Le fichier texte caractre par caractre ................................................................................................. 101 6.3.4. Le fichier texte ligne par ligne ............................................................................................................. 102 6.3.5. La taille dun fichier ............................................................................................................................. 103 6.3.6. Renommer et supprimer un fichier comme en C ................................................................................. 103 6.3.7. Copier, renommer et supprimer un fichier avec les commandes du systme dexploitation ............... 103

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 5

    1. Conventions d'criture Afin de permettre au lecteur de diffrencier rapidement diverses parties du texte, la rdaction et la mise en page de ce cours sont ralises autant que possible dans le respect des rgles suivantes. Mots du langage et mots du programmeur. Les mots des langages sont crits dans le texte courant en Courier New gras. Il en est de mme pour les mots utiliss par le programmeur dans les lignes de codes des exemples, mais ceux-ci sont franciss. Ex. :

    le contrle daccs n'est pas assur car la variable Cinq dclare public est accessible les portes public et private sont

    Programme complet et extraits. Les lignes de codes des exemples sont cadres gauche lorsqu'elles constituent un programme complet, mme si son code est entrecoup de textes explicatifs, et elles sont dcales d'un retrait vers la droite lorsqu'elles constituent un extrait de programme. Exemple de programme complet : #include "stdafx.h" using namespace std; void main() { cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 6

    2. Avertissements La connaissance du langage C est ncessaire la comprhension des propos et des exemples prsents dans ce cours. La syntaxe du C, ses structures de programmation, ses types et ses structures des donnes, ses fonctions intrinsques et ses mcanismes procduraux sont gnralement considrs comme connus et ne sont pas expliqus dans ces pages. Lobjet de ce cours est de faire acqurir par les tudiants, les divers concepts qui rgissent une programmation oriente objet bien pense. Ce cours, qui nest donc pas un cours de langage de programmation, doit toutefois sappuyer sur un langage pour produire les exemples et exercices ncessaires lillustration des concepts tudis. Plusieurs langages sont susceptibles de convenir ces fins, mais cest le langage C++ qui est utilis dans ces pages. Malgr de larges dtours dtudes syntaxiques imposes par les particularits de ce langage, le C++ nest pas enseign en dtail et seuls ses aspects utiles lobjet du cours sont expliqus. Les programmes repris dans ce cours sont censs tre illustratifs et non tre toute preuve. Bien que gnralement de bonne facture, ils nont pas subi de tests approfondis. Le programmeur souhaitant en intgrer dans un dveloppement aura soin de pratiquer les tests ncessaires la fiabilit de son application. 3. Rfrences pour le langage 3.1. Sur internet http://www.cppreference.com/wiki/ http://www.nawouak.net/?lang=fr 3.2. Fichiers distribus 3.2.1. Les livres Cours de C/C++ par Christian Casteyde Penser en C++ par Bruce Eckel 3.2.2. Les supports de cours Cours de C++ par Maude Manouvrier C++: l'essentiel par Justus H. Piater 3.3. Bibliographie Apprendre le C++, Claude Delannoy, Eyrolles, 2007.

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 7

    4. Approche syntaxique du langage C++ Le langage C++ est vraiment trs semblable au langage C, du moins dans ses aspects procduraux. Lapproche syntaxique prsente ici a pour objet de rvler les principales diffrences entre les deux langages sans toutefois entrer dans une comparaison systmatique, fastidieuse et lassante, et sans doute inutile ds lors que lobjet du cours nest pas ltude du langage, mais seulement son appropriation en vue de lexprimentation de la POO. 4.1. Les commentaires Un commentaire scrit la suite du dlimiteur // et se termine avec la fin de la ligne. Un tel commentaire peut donc tre une ligne complte ou seulement une fin de ligne. Les dlimiteurs du C peuvent toujours tre utiliss pour isoler plusieurs lignes de codes, par exemple. Dans un tel bloc de commentaires, ceux qui sont initis par // ne sont pas considrs comme tant imbriqus (les imbrications de blocs de commentaires /* */ tant interdites). 4.2. Le caractre de continuation Le caractre de continuation est le \ seul en fin de ligne. Il permet lcriture dune longue ligne de code sur plusieurs lignes. cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 8

    4.4. Valeur, pointeur et rfrence La notion de valeur est bien connue de tous les programmeurs. Dans lexemple suivant, N est de type valeur et si cette variable est utilise en paramtre effectif dune fonction F, cest une copie de la variable qui est rellement passe la fonction. Cest pour cette raison que la modification dune telle valeur dans une fonction naffecte pas la variable du programme appelant.

    int N(7); cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 9

    Le plus important finalement, est de savoir quune rfrence est un alias et que dsigner une chose (ou une personne) par son nom ou par son surnom (son alias) revient toujours dsigner la mme chose, la mme personne. Cest pourquoi, ds lors quune variable possde une rfrence, il est permis dutiliser son identificateur ou son alias. Mais la rfrence est un pointeur dont la gestion est transparente pour le programmeur et donc, un pointeur quand mme !

    Pointeur Rfrence Le pointeur peut tre raffect par la suite. int N(0); int * pI = &N;

    int M(7); pI = &M; Aprs cette dernire ligne, la valeur pointe par pI est la variable M dont la valeur est 7. Maintenant, pI pointe M.

    La rfrence ne peut tre modifie. int N(0); int & rI(N);

    int M(7); rI = M;

    Aprs cette dernire ligne, la valeur de N est 7 et rI rfrence toujours N.

    Le pointeur peut tre initialis ou raffect dynamiquement. pI = (int *) malloc(sizeof(int));

    La rfrence doit tre initialise par une LValue (ou par une valeur littrale, cas spcial suivant). Elle ne peut donc pas tre initialise de faon dynamique (ex. par malloc).

    Un pointeur, mme dclar const, ne peut tre affect par une valeur littrale. Les expressions suivantes sont interdites. int *pI = 0X0012F0B0; const int *pI = 0X0012F0B0;

    Une rfrence dclare const peut tre affecte par une valeur littrale. Lexpression suivante est valide. const int & rI = 1234; Une variable invisible cre par le compilateur contient la valeur 1234, mais seule sa rfrence est disponible.

    Le type dune fonction (de sa valeur de retour) peut tre un pointeur.

    int * UneFct() {// } Le type dune fonction (de sa valeur de retour) peut tre une rfrence.

    int & UneFct() {// } A noter que la dclaration dune rfrence dans une fonction, en vue du retour dune valeur locale, doit stipuler cette valeur static pour que celle-ci survive lachvement de la fonction.

    Le pointeur a une adresse mmoire diffrente de celle de sa valeur pointe. Il ncessite donc lespace ncessaire pour contenir une adresse en plus de celui des donnes. int N(0); int * pI = &N; cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 10

    4.5. Le qualificatif const Le mot rserv const est utilis pour dfinir une donne qui ne peut tre modifie en cours dexcution, ni mme dans la suite du projet en cours de dveloppement. Bien que prsent dans pratiquement tous les langages, le programmeur C use frquemment de la directive #define qui produit le mme effet, savoir limpossibilit de modifier la valeur ensuite. Il faut toutefois noter que le mcanisme de #define est diffrent et sert lcriture de macros. Par exemple, les lignes suivantes dfinissent les macros MAX et CARRE, ainsi quune constante Pi (plus communment appele constante symbolique).

    #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define CARRE(a) ((a) * (a)) #define Pi 3.141592

    Mais, que du point de vue du programmeur, il sagisse dune macro ou dune constante, le mcanisme est dans tous les cas celui de la macro, cest un mcanisme de substitution : tout appel de MAX, CARRE ou Pi dans le code est remplac la pr-compilation par le code de la macro elle-mme. Une valeur telle que Pi dans cet exemple est stocke en mmoire parmi les codes du programme, dans le code segment qui lui est allou. A la suite des #define ci-dessus, les lignes suivantes : sont compiles comme tant :

    M = MAX(x, y); Surface = CARRE(Cote); Perimetre = Diametre * Pi;

    M = (((x) > (y)) ? (x) : (y)); Surface = ((Cote) * (Cote)); Perimetre = Diametre * 3.141592;

    Le mcanisme de la vritable constante est diffrent : il sagit bien dune dfinition avec initialisation dune variable non modifiable, mais variable quand mme en ce sens quelle possde bien une place en mmoire, dans un des espaces rservs aux donnes du programme, dans un data segment par exemple. 4.5.1. Dclaration et initialisation Les valeurs dclares constantes doivent tre initialises. Les deux dclarations suivantes sont synonymes.

    const int X(17); int const X(17);

    4.5.1.1. Pointeur sur une valeur constante Un pointeur sur une valeur constante doit tre dclar comme tel.

    const int X(7); // Dclaration dun entier constant // int *pI = &X; // Interdit car X est constant const int *pI = &X; // Permis car pI est dclar pointeur dun entier constant

    4.5.1.2. Pointeur dune valeur constante Il est permis dinitialiser un pointeur de valeur constante avec une valeur non constante. La valeur pointe donne accs une constante tandis que la variable donne accs une valeur modifiable.

    int X(7); X++; // Permis car X n'est pas constant const int *pI = &X; // Permis mme si X nest pas une constante *pI++; // Incrmente le pointeur pI qui ne pointe donc plus X ensuite // (*pI)++; // Interdit car la valeur pointe est rpute constante

    Il est bien entendu aussi permis dinitialiser un pointeur de valeur constante avec une valeur constante du type adquat. La valeur pointe et la constante donnent accs une valeur non modifiable.

    const int X(7); // Une constante doit tre initialise const int *pI = &X; // Permis car pI est dclar pointeur dun entier constant *pI++; // Incrmente le pointeur pI qui ne pointe donc plus X ensuite // (*pI)++; // Interdit car la valeur pointe est rpute constante

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 11

    4.5.1.3. Pointeur constant dune valeur quelconque Un pointeur peut tre dclar constant. Il ne peut plus alors faire lobjet dincrmentation ou dcrmentation, ni de raffectation.

    int X(7); int * const pI = &X; // Permis mme si X nest pas une constante // *pI++; // Interdit car le pointeur est dclar constant (*pI)++; // Incrmente la valeur pointe qui nest pas une constante X++; // Permis car X n'est pas une constante

    4.5.1.4. Pointeur constant dune valeur constante Un pointeur dune valeur constante peut tre dclar constant. Le pointeur et sa valeur pointe sont alors non modifiables.

    int X(7); const int * const pI = &X; // Permis car pI est un pointeur sur un entier constant // *pI++; // Interdit car le pointeur est dclar constant // (*pI)++; // Interdit car la valeur pointe est un entier constant X++; // Permis car X n'est pas une constante

    4.5.1.5. Pointeur constant sur une valeur constante Un pointeur peut tre dclar constant et tre initialis avec une valeur constante. Le pointeur et sa valeur pointe sont alors non modifiables.

    const int X(7); const int * const pI = &X; // Permis car pI est un pointeur sur un entier constant // *pI++; // Interdit car le pointeur est dclar constant // (*pI)++; // Interdit car la valeur pointe est un entier constant // X++; // Interdit car X est un entier constant

    4.5.1.6. Rfrences et constantes

    const int X(7); // int & rI = X; // Interdit car X est constant const int & rI = X; // Permis car rI est dclare rfrence sur un entier constant

    int X(7); const int & rI = X; // Permis mme si X nest pas une constante X++; // Permis car X nest pas une constante // rI++; // Interdit car la valeur rfrence est constante

    int X(7); int & const rI = X; // Permis, mais une rfrence est toujours non modifiable X++; // Permis car X nest pas une constante rI++; // Permis car la valeur rfrence nest pas constante

    4.5.1.7. Tableaux et constantes

    const int Taille(3) ; // Usage dune valeur constante pour rserver un tableau char Ch[Taille] ; // Rservation dun vecteur pour 3 caractres stocks aux

    // indices 0, 1 et 2, lindice 3 recevant le terminateur '\0' const int T[] = {10, 20, 30}; // Dclaration dun vecteur de 3 entiers constants // T[2]++; // Interdit car les valeurs du vecteur sont des constantes

    4.5.2. Le qualificatif const et les arguments des fonctions Comme illustr ci-aprs, le mot const peut tre employ pour protger des donnes passes par pointeurs ou par rfrences des fonctions. Le mot const dans le prototype dune fonction est la garantie pour le programmeur que cette fonction naltrera pas ses donnes.

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 12

    Les consquences sur les valeurs des variables des codes appelants sont diffrentes selon que les paramtres sont passs aux fonctions par valeurs, ou par pointeurs, ou par rfrences. Dans le cas du passage par valeur, cest une copie de la donne qui est transmise la fonction. Les modifications exerces sur cette copie naffectent videmment pas la variable dorigine. Il est toutefois permis de qualifier les arguments de constant et alors, la copie de la variable transmise devient une constante locale.

    int DeuxFois(int X) { X = X * 2; // La fonction manipule une copie de la variable dorigine return X; // et retourne la copie modifie }

    int DeuxFois(const int X) { return (X * 2); // Impossible de modifier la copie de la variable dorigine }

    Dans le cas du passage par pointeur, la copie du pointeur qui est transmise la fonction est ladresse des donnes. Si les modifications du pointeur peuvent souvent tre ignores, les modifications des valeurs pointes quant elles sont bien rpercutes au niveau du code appelant.

    int T[] = {10, 20, 30}; // FP(T, 1); // void FP(int * X, int i) { *(X+i) += 10; // La valeur 20 de T[1] est remplace par la valeur 30 } void FP(const int * X, int i) { // *(X+i) += 10; // Interdit car X est un pointeur dentiers constants } void FP(int * const X, int i) { *(X+i) += 10; // La valeur 20 de T[1] est remplace par la valeur 30 } // Cest le pointeur qui est constant ici. X++ serait une erreur

    Dans le cas du passage par rfrence, cest ladresse de la variable qui est rellement passe la fonction et toute manipulation de la rfrence manipule la variable rfrence. typedef int TInt [10]; TInt T = {10, 20, 30}; TInt & rT = T;

    // FR(rT, 1); // void FR(TInt & X, int i) { X[i] += 10; // La valeur 20 de T[1] est remplace par la valeur 30 } void FR(const TInt & X, int i) { // X[i] += 10; // Interdit car X rfrence des entiers constants }

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 13

    4.6. Les librairies De nombreuses libraires standard du C ont t redfinies (et amliores) en C++ de sorte permettre au programmeur dutiliser ses fonctions familires et que ces fonctions soient tout--fait compatibles avec les spcificits du C++ (par exemple, les fonctions ne sont pas surchargeables en C, mais doivent ltre en C++). Les librairies ainsi reconverties du C sont lgrement renommes : le nom est prcd dun c et lextension est supprime. Par exemple, stdio.h est devenue cstdio. Ces librairies sont notamment : cassert, cctype, cerrno, cfloat, ciso646, climits, clocale, cmath, csetjmp, csignal, cstdarg, cstddef, cstdio, cstdlib, cstring, ctime, cwchar, cwctype. Toutes ces librairies, de mme que celles spcifiques C++, comme iostream et string, dfinissent leurs symboles dans un espace de noms std rserv pour la bibliothque standard C++. Pour utiliser les fonctionnalits dune libraire, il suffit dinclure la librairie requise dans le code source et de dsigner lespace de nom concern.

    #include #include //

    std::printf("Bonjour le monde"); std::printf("La racine carre de 100 est : %lf\n", std::sqrt(100.)); Lusage dune clause using permet dviter les rptitions agaantes de std::.

    #include #include using namespace std; //

    printf("Bonjour le monde"); printf("La racine carre de 100 est : %lf\n", sqrt(100.)); 4.7. Les instructions dentres et de sorties standards Comme partiellement illustrs par les exemples prcdents, les instructions dE/S du langage C sont toujours disponibles en C++, ventuellement par linclusion de la librairie cstdio (et non de stdio.h dont les fonctions ne rpondent pas aux spcifications de la programmation oriente objet). La bibliothque standard C++ dfinit dans lentte iostream des classes extrmement puissantes permettant de manipuler les flux dE/S. Ces classes ralisent en particulier les oprations dE/S de et vers les priphriques dentre et les priphriques de sortie standards (gnralement, le clavier et lcran), mais elles ne sarrtent pas l : elles permettent galement de travailler sur des fichiers ou encore sur des tampons en mmoire. Les classes dE/S de la bibliothque standard C++ permettent donc deffectuer les mmes oprations que les fonctions printf et scanf de la bibliothque reconvertie du C standard. Cependant, grce au mcanisme de surcharge des oprateurs, elles sont beaucoup plus faciles dutilisation. En effet, les oprateurs > de ces classes ont t surchargs pour chaque type de donne du langage, permettant ainsi de raliser des E/S types extrmement facilement. Loprateur , ou oprateur dextraction, permettra de raliser la lecture dune nouvelle donne dans le flux dentre. Ces deux oprateurs renvoient tous les deux le flux de donnes utilis, ce qui permet de raliser plusieurs oprations dE/S successivement sur le mme flux. La bibliothque standard dfinit quatre instances particulires de ses classes dE/S : cin, cout, cerr et clog. Ces objets sont des instances des classes istream et ostream, prenant respectivement en charge lentre et la sortie des donnes des programmes. Lobjet cin correspond au flux dentre standard stdin du programme, et lobjet cout aux flux de sortie standard stdout. Enfin, les objets cerr et clog sont associs au flux derreurs standard stderr. Thoriquement, cerr doit tre utilis pour lcriture des messages derreur des programmes, et clog pour les messages dinformation. Cependant, en pratique, les donnes crites sur ces deux flux sont crites dans le mme flux, et lemploi de lobjet clog est assez rare. De plus, la bibliothque standard dfinit des manipulateurs permettant de raliser des oprations simples sur les flux dE/S. Le manipulateur le plus utilis est certainement le manipulateur endl qui, comme son nom lindique, permet de signaler une fin de ligne et deffectuer un saut de ligne lorsquil est employ sur un flux de sortie.

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 14

    Les avantages des flux C++ sont nombreux, notamment : le type des donnes est automatiquement pris en compte par les oprateurs dinsertion et dextraction (ils sont

    surchargs pour tous les types prdfinis); les oprateurs dextraction travaillent par rfrence (on ne risque plus domettre loprateur & dans la fonction

    scanf); il est possible de dfinir des oprateurs dinsertion et dextraction pour dautres types de donnes que les types de

    base du langage; leur utilisation est globalement plus simple. Les flux dE/S dfinis par la bibliothque C++ sont donc dune extrme souplesse et sont extensibles aux types de donnes utilisateur. Par ailleurs, ils disposent dun grand nombre de paramtres de formatage et doptions avances. 4.7.1. Quelques manipulateurs de la classe ostream

    endl Envoie un caractre de retour la ligne sur le flux et synchronise le tampon par un appel la mthode flush.

    flush Synchronise le tampon utilis par le flux par un appelle la mthode flush. boolalpha Active le formatage des boolens sous forme textuelle. noboolalpha Dsactive le formatage textuel des boolens. hex Formate les nombres en base 16. oct Formate les nombres en base 8. dec Formate les nombres en base 10. fixed Utilise la notation en virgule fixe pour les nombres virgule. scientific Utilise la notation en virgule flottante pour les nombres virgule. left Aligne les rsultats gauche. right Aligne les rsultats droite. showbase Indique la base de numrotation utilise (usage conjoint avec hex, oct ou dec). noshowbase Nindique pas la base de numrotation utilise. showpoint Utilise le sparateur de virgule dans les nombres virgule, mme si la partie

    fractionnaire est nulle. noshowpoint Nutilise le sparateur de virgule que si la partie fractionnaire des nombres virgule

    flottante est significative. setbase(int base) Permet de slectionner la base de numrotation utilise. Les valeurs admissibles sont

    8, 10 et 16 respectivement pour la base octale, la base dcimale et la base hexadcimale.

    setprecision(int) Permet de spcifier la prcision (nombre de caractres significatifs) des nombres formats.

    setw(int) Permet de spcifier la largeur minimale du champ dans lequel la donne suivante sera crite la prochaine opration dcriture sur le flux.

    setfill(char_type) Permet de spcifier le caractre de remplissage utiliser lorsque la largeur des champs est infrieure la largeur minimale spcifie dans les options de formatage.

    showpos crit systmatiquement le signe des nombres, mme sils sont positifs. noshowpos Ncrit le signe des nombres que sils sont ngatifs. uppercase crit les exposants et les chiffres hexadcimaux en majuscule. nouppercase crit les exposants et les chiffres hexadcimaux en minuscule.

    4.7.2. Quelques manipulateurs de la classe istream

    boolalpha Active linterprtation des boolens sous forme de textuelle. noboolalpha Dsactive linterprtation des boolens sous forme textuelle. hex Utilise la base 16 pour linterprtation des nombres entiers. oct Utilise la base 8 pour linterprtation des nombres entiers. dec Utilise la base 10 pour linterprtation des nombres entiers. skipws Ignore les espaces lors des entres formates. noskipws Conserve les espaces lors des entres formates. ws Supprime tous les espaces prsents dans le flux dentre jusquau premier caractre

    non blanc.

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 15

    4.7.3. Exemples de saisies diverses

    int i; double f; char tc[30], c; cout > i; cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 16 cout > c; cin.ignore(); // Vide le buffer du \n rsiduel cout f; cin.ignore(); // Vide le buffer du \n rsiduel cout n; cout
  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 17

    Toutes les conversions vers un pointeur gnrique sont implicites. Les conversions inverses ncessitent une conversion explicite (cast).

    int i; float f; double d; string ch = "Coucou"; int * pI = &i; float * pF = &f; double * pD = &d; string * pS = &ch; void * pVide = pS; // Conversion implicite pVide = pD; // Conversion implicite pVide = pI; // Conversion implicite pF = (float *) pVide; // Conversion explicite (cast)

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 18

    4.9. Les paramtres optionnels Un paramtre est optionnel lorsquon lui attribue une valeur par dfaut, cest--dire une valeur qui sera affecte en cas dabsence du paramtre effectif correspondant lors de lappel de la fonction. Cette valeur par dfaut se dfinit lors de la dclaration de la fonction ou lors de sa dfinition, ou encore dans les deux cas. Mais il est prfrable de dfinir les paramtres optionnels au niveau des dclarations, ceci est dailleurs obligatoire lorsque ces dclarations sont faites dans un fichier distinct (fichier dentte .h). Dans un cas comme dans lautre, lorsquun argument est flanqu dune valeur par dfaut, il doit en tre de mme pour tous les arguments suivants. Si des arguments ne doivent pas recevoir de valeur par dfaut, ils doivent tre dclars dabord. // Prototypes

    // Le seul argument est optionnel, sa valeur par dfaut est 3 void F1(int = 3); // Le dernier argument est optionnel, sa valeur par dfaut est 2.35 void F2(int, float = 2.35); // Aucun argument nest optionnel ici mais cela peut encore tre fait lors de la dfinition void F3(char, int, float); // Les 2 derniers arguments sont optionnels void F4(char, int, int = 0, float = 3.14); // Dfinitions // Ne pas remettre la valeur par dfaut, elle est dfinie dans le prototype void F1(int n) { // ; } // Ne pas remettre la valeur par dfaut, elle est dfinie dans le prototype void F2(int n, float x) { // ; } // Attribution des valeurs par dfaut aux 2 derniers arguments qui deviennent optionnels void F3(char c, int n = 3, float x = 2.35) { // ; } // Attribution dune valeur par dfaut au 2me argument qui devient optionnel comme // ltaient dj les 2 derniers (dfinis dans le prototype) void F4(char c, int n1 = 0, int n2, float x) { // ; }

    Lors de lappel dune fonction, si un paramtre optionnel est omis, les suivants doivent tre omis aussi. // Appels des fonctions

    char a = 0; int i1, i2 = 2; float r = 5.6; // // Appel de F1 avec un paramtre effectif, sa valeur par dfaut est ignore F1(i2); // Appel de F1 sans paramtre effectif, sa valeur par dfaut remplace le paramtre absent F1(); // Lappel interdit car le 1er paramtre de F2 nest pas optionnel // F2(); // Appel de F2 sans le 2me paramtre effectif, sa valeur par dfaut le remplace F2(i2); // Appel de F2 avec tous les paramtres effectifs, la valeur par dfaut est ignore F2(i2, r);

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 19 // Appel de F4 avec tous les paramtres effectifs, les valeurs par dfaut sont ignores F4(a, i1, i2, r); // Appel de F4 avec un paramtre absent interdit, sauf si cest le dernier // F4(a, , i2, r); // Appel de F4 avec le dernier paramtre effectif absent F4(a, i1, i2);

    // Si le 2me paramtre effectif doit tre omis, il faut que les suivants le soient aussi F4(a);

    4.10. La fonction inline La dfinition dune fonction peut tre prfixe du mot cl inline. Il sagit de la demande au compilateur de remplacer les appels cette fonction par le corps mme de la fonction, comme cela se fait avec les macros. Toutefois, contrairement aux macros, il ne sagit pas dune directive (inconditionnelle) au pr-compilateur, mais bien dune demande au compilateur qui peut lexaucer ou au contraire, traiter cette fonction comme toute autre. Attention, une fonction inline ne peut tre une fonction rcursive et il nest pas permis de pointer une telle fonction (pas de pointeur sur fonction).

    inline int DeuxFois(int X) { return (X * 2); } 4.11. Le type boolen Une variable de type bool peut avoir une des deux valeurs : false et true. Une telle variable occupe 1 octet en mmoire. En fait, en C++, ce type nest autre quune numration : typedef enum {false = 0, true} bool;

    bool V; int a = 3, b = 5, c = 0; // V = a > b; cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 20

    4.12. Le type string La classe basic_string de la bibliothque standard, dclare dans lentte string, facilite le travail du programmeur et permet dcrire du code manipulant des textes de manire beaucoup plus sre. En effet, cette classe encapsule les chanes de caractres C classiques et fournit des services extrmement intressants. En particulier, la classe basic_string dispose des caractristiques suivantes : compatibilit quasi-totale avec les chanes de caractres C standard; gestion des chanes taille variable; prise en charge de lallocation dynamique de la mmoire et de sa libration en fonction des besoins et de la taille

    des chanes manipules; dfinition des oprateurs de concatnation, de comparaison et des principales mthodes de recherche dans les

    chanes de caractres; intgration totale dans la bibliothque standard, en particulier au niveau des flux dE/S. Il nest pas question dentreprendre ici ltude dtaille de ce type de donne, mais voici quelques exemples dutilisation des principaux outils de la classe. La classe propose divers constructeurs qui sont autant de moyens dinitialiser une chane au moment de sa dclaration. Voici quelques exemples :

    char C4[] = "Qwerty"; char * C5 = "Panzani"; char C6[5] = {'A','z','e','r','\0'}; string Ch0; // Chane vide string Ch1(5, 'c'); // Chane compose de 5 c string Ch2("Voici un mot ..."); // La chane littrale string Ch3(Ch2, 9, 3); // 3 caractres de Ch2 partir de l'indice 9 string Ch4(C4); // A partir dun vecteur de char string Ch5(C5); string Ch6(C6); string Ch7(C6, 3); // 3 caractres de C6 partir de l'indice 0 cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 21

    Affectation dune chane une autre : assign. La mthode offre plus de possibilits quune simple affectation.

    Ch0.assign(Ch2, 9, 3); cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 22 Ch0.erase(9, 3); // Efface 3 caractres partir de lindice 9 cout
  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 23

    Remplacement de caractres : replace.

    Ch0 = "Voici le mot ..." ; Ch0.replace(9, 3, "XX"); cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 24

    4.13.3. Surdfinition dune fonction Semblable la surcharge (overload) des fonctions en ce sens quelle permet lcriture de fonctions homonymes, la surdfinition (overwrite) (ou redfinition) est cependant fort diffrente : cest un mcanisme de POO qui permet le vrai polymorphisme; les fonctions redfinies doivent avoir la mme signature; une fonction et sa redfinition ne peuvent se situer lintrieur dune mme classe. 4.14. Allocation dynamique de la mmoire Deux fonctions ont la charge de la rservation despace mmoire. Ce sont les fonctions new et new[]. Malgr leur ressemblance, ces fonctions sont diffrentes lusage et chacune possde sa propre fonction de dsallocation, respectivement delete et delete[]. Les fonctions new et delete sont destines la gestion de la mmoire des types scalaires et des objets, tandis que new[] et delete[] sont destines la gestion de la mmoire des tableaux.

    // Les allocations int * pInt = new int; // Pour un entier int * pInt = new int[100]; // Pour un tableau de 100 entiers UnObjet * pUnObjet = new UnObjet; // Pour un objet UnObjet * pUnObjet = new UnObjet[100]; // Pour un tableau de 100 objets // Les dsallocations correspondantes delete pInt; // Pour lentier delete[] pInt; // Pour le tableau de 100 entiers delete pUnObjet; // Pour lobjet delete[] pUnObjet; // Pour le tableau de 100 objets

    Les adresses alloues en une mme opration new[] sont conscutives en mmoire et larithmtique des pointeurs est donc possible.

    int * pInt = new int[10]; for (int i = 0; i < 10; i++) *(pInt + i) = i; for (int i = 0; i < 10; i++) cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 25

    Lespace destin aux variables globales et aux variables statiques est allou dans le data segment au dmarrage du programme. Il nest libr qu la fin de lexcution du programme.

    Zone mmoire Occupation des adresses Usage Type de donnes Data segment selon les adresses croissantes Variables globales et statiques Donnes statiques Pile selon les adresses dcroissantes Variables locales, paramtres, valeur de retour Donnes automatiques Tas selon les adresses croissantes Objets et allocations dynamiques Donnes dynamiques

    4.14.2. Contrle des erreurs dallocation Lorsquil ny a pas assez de mmoire disponible, les oprateurs new et new[] peuvent se comporter de deux manires selon limplmentation. Le comportement le plus rpandu est de renvoyer un pointeur NULL. Cependant, la norme C++ indique un comportement diffrent : si loprateur new manque de mmoire, il doit appeler un gestionnaire derreur. Ce gestionnaire ne prend aucun paramtre et ne renvoie rien. Selon le comportement de ce gestionnaire derreur, plusieurs actions peuvent tre faites : 1. soit ce gestionnaire peut corriger lerreur dallocation et rendre la main loprateur new (le programme nest donc

    pas termin), qui effectue une nouvelle tentative pour allouer la mmoire demande; 2. soit il ne peut rien faire. Dans ce cas, il peut mettre fin lexcution du programme ou lancer une exception

    std::bad_alloc, qui remonte alors jusqu la fonction appelant loprateur new. Cest le comportement du gestionnaire install par dfaut dans les implmentations conformes la norme.

    Loprateur new est donc susceptible de lancer une exception std::bad_alloc quil convient dintercepter pour permettre la gestion de lerreur et empcher les tentatives en boucle dallocation de la mmoire. Il est possible de remplacer le gestionnaire derreur appel par loprateur new laide de la fonction set_new_handler. Cette fonction de la librairie gnrale C++ peut ncessiter la directive #include . Elle attend en paramtre un pointeur sur la fonction de gestion derreur crite cet effet, qui ne prend aucun paramtre et ne renvoie rien.

    void MonTraitementMemoireFaible(); // Prototype de la fonction appeler set_new_handler(MonTraitementMemoireFaible); // char *pC = new char[0x7fffffff]; // Cest beaucoup ! //

    void MonTraitementMemoireFaible() // Dfinition de la fonction de gestion {

    // essayer de librer de la mmoire cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 26

    Il faut sattendre ce quun jour, tous les compilateurs C++ lancent une exception en cas de manque de mmoire lors de lappel loprateur new, puisque cest impos par la norme. Il est toutefois possible de ne pas devoir grer lexception comme ci-dessus et de continuer recevoir un pointeur NULL en cas de manque de mmoire. Il faut pour cela fournir le paramtre appropri new : la bibliothque standard dfinit lobjet constant nothrow cet usage.

    char *pC = new(nothrow)char[0x7fffffff]; // Cest beaucoup ! if (pC==NULL) {

    cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 27

    5. La programmation oriente objet 5.1. Introduction 5.1.1. Depuis 1960 L'approche objet, incontournable aujourd'hui, n'est pas une ide neuve. Ds le dbut des annes soixante en Norvge, Ole-Johan Dahl et Kristen Nygaard crent le langage Simula (Simple universal language). Ce langage, qui est driv de l'Algol 60, se prsente comme un Algol intgrant de nouveaux concepts de programmation, dont celui de la programmation oriente objet. C'est pourquoi Simula est reconnu comme tant le premier langage orient objet. Par Simula, on entend gnralement Simula-67, c'est--dire la deuxime version commercialise, celle de 1967. Un pas important vers la programmation oriente objet est fait ensuite au dbut des annes septante avec l'arrive du langage Smalltalk, inspir de Lisp et de Simula, qui implmente notamment les concepts d'enveloppement, d'hritage et de polymorphisme. C'est de l'volution des concepts et techniques de Smalltalk, que drivent les langages orients objets tels que C++ (cr par Bjarne Stroustrup en 1982), Delphi, Eiffel, Python, Ruby, Loops, et surtout, Java, Delphi.Net, C.Net, VB.Net, C#.Net. 5.1.2. Quelles diffrences ? En programmation procdurale, les instructions sont runies en sous programmes (procdures ou fonctions) qui ont pour objet le traitement de donnes dfinies par ailleurs. Les fonctions, procdures et autres suites dinstructions accdent aux zones o sont stockes les donnes. Les donnes et leurs moyens de traitements sont dissocis. En programmation oriente objet, un programme est vu comme un ensemble dentits. Ces entits regroupent les donnes et les instructions ncessaires leur traitement. Au cours de l'excution du programme, les entits collaborent et senvoient des messages ncessaires au bon droulement des traitements. Un objet reprsente une entit du monde rel, ou d'un monde virtuel dans le cas dun objet immatriel, qui se caractrise par une identit, des tats significatifs et par un comportement. Lidentit dun objet permet de distinguer les objets les uns par rapport aux autres. Son tat correspond aux valeurs de tous ses attributs un instant donn. Enfin, le comportement dun objet est dfini par lensemble des oprations quil peut excuter en raction aux messages qu'il reoit des autres objets. Ces messages sont essentiellement des ordres lancs par les objets afin de faire excuter une tche par le destinataire ou d'en obtenir une information. Mme si une classe peut tre drive de nombreuses autres (par hritage), l'objet reste nanmoins l'instance dune et une seule classe : sa classe dappartenance, son type. Elle est un modle dcrivant le contenu et le comportement des futurs objets de la classe. C'est dans cette classe que sont dfinies les proprits et les oprations de lobjet. Une classe est labstraction dun ensemble dobjets qui possdent une structure identique (liste des attributs) et un mme comportement (liste des oprations). Ainsi, contrairement l'approche procdurale qui dissocie donnes et traitements, lapproche objet se caractrise par le regroupement dans une mme classe de la description des donnes (appeles attributs, proprits ou donnes membres) et des oprations de traitements (appeles mthodes ou fonctions membres). Ce regroupement est lenveloppement, principe initial de la POO, qui amliore lautonomie et lindpendance de chaque classe et augmente le potentiel de rutilisation de chacune delles. Attention, les concepts procduraux de la programmation ne sont pas jeter. Les moyens de traitements sont crits dans les classes par de la programmation procdurale.

    Traitement 1

    Traitement 2

    Traitement

    Traitement n

    Donnes

    Objet 1 Traitements 1

    Donnes 1

    Objet 2 Traitements 2

    Donnes 2

    Objet Traitements

    Donnes

    Objet n Traitements n

    Donnes n

    Communications

    Programmation objet Programmation procdurale

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 28

    Les concepts fondamentaux de la programmation oriente objet sont lenveloppement, le contrle daccs, l'hritage et le polymorphisme. Pour certains auteurs, enveloppement et encapsulation sont synonymes et le contrle daccs porte le nom dabstraction. Pour dautres, lencapsulation est lassociation de lenveloppement et du contrle daccs. 5.1.3. Un autre niveau de programmation Il est impratif de faire la distinction entre la programmation consommatrice des objets et la programmation productrice de ces objets. Le programmeur objet est le plus souvent amen concevoir et produire des classes qui sont exploites par dautres, par ceux qui ralisent les applications finales. Cest ce qui rend important le contrle daccs : il nest pas question quun programmeur client puisse modifier quoi que ce soit lintrieur dune classe, nimporte comment, sans vraiment savoir ce quil fait. Le programmeur client ne peut exploiter une classe que par lusage des mthodes exposes son intention. 5.2. Classe et structure Voici une classe MonEntierClass. Par dfaut, tous les membres de la classe sont private et donc inaccessibles de lextrieur. Linterface de la classe est ralise par les mthodes dfinies sous la mention public. La mention private peut tre omise (dans cet ordre dcriture de la classe).

    class MonEntierClass { private :

    int i; // Donne membre de type entier public :

    int Lit_i(void) // Mthode de lecture de la donne {

    return i; } void Ecrit_i(int valeur) // Mthode dcriture de la donne {

    i=valeur; }

    }; Voici une structure MonEntierStruct. Par dfaut, tous les membres de la structure sont public et donc accessibles de lextrieur sans aucun contrle. Linterface de la structure est ralise par les mthodes dfinies sous la mention public, mention qui peut tre omise (dans cet ordre dcriture de la structure). La mention private quant elle est ncessaire sil est souhaitable de contrler laccs la donne.

    struct MonEntierStruct { public :

    int Lit_i(void) // Mthode de lecture de la donne {

    return i; } void Ecrit_i(int valeur) // Mthode dcriture de la donne {

    i=valeur; }

    private : int i; // Donne membre de type entier

    }; En C++, il ny a pas dautres diffrences entre structure et classe en matire de POO. Une classe peut driver dune structure et vice versa. Elles sont instancies et utilises toutes les deux de la mme manire.

    MonEntierClass MonIntC; MonEntierStruct MonIntS; MonIntC.Ecrit_i(17); cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 29

    5.3. Ecriture dune classe et namespace La classe MonEntierClass crite ci-avant contient la dfinition complte de chacun de ses membres. Il est cependant usuel de dfinir une classe par les dclarations de ses donnes membres et les prototypes de ses mthodes, ces dernires tant alors dfinies hors de la classe.

    class MonEntierClass { private : int i; public : int Lit_i(void); void Ecrit_i(int); }; void MonEntierClass::Ecrit_i(int valeur) { MonEntierClass::i = valeur; } int MonEntierClass::Lit_i(void) { return MonEntierClass::i; }

    Il est impratif dindiquer quelle classe appartient une mthode dfinie. Cela se fait par lusage de loprateur ::, nomm oprateur de rsolution de porte. Cet oprateur permet lutilisation au sein dune mme portion de codes, de fonctions et variables homonymes. Il permet donc dviter le masquage dune variable globale par une variable locale de mme nom. En C++, une variable globale appartient au namespace par dfaut, le global namespace. Loprateur de rsolution de porte fait la distinction entre des lments homonymes, mais dorigines (de type namespace ou class) diffrentes.

    int N = 111; // Variable globale N namespace MonProg // Dfinition dun namespace { int N = 222; // Variable N de MonProg } void main() { int N = 333; // Variable locale N cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 30 void MonEntierClass::Ecrit_i(int valeur) {

    int i = 2; this->i = valeur * i; // Le rappel indispensable, emploi de this }

    Loprateur this, pointeur de linstance en cours, ne peut tre utilis qu lintrieur des mthodes membres. 5.4. Ecriture modulaire des classes et des programmes En C++, la possibilit de dfinir les mthodes des classes en dehors de celles-ci permet de scinder lcriture des classes en deux fichiers : 1. un fichier d'entte (.h, .hh, .H) comportant la dclaration des attributs (donnes membres spcifiques lobjet

    modlis), les prototypes des mthodes (fonctions membres) et les degrs de visibilit (private, public, protected);

    2. un fichier d'implmentation (.cpp, .cc, .C) comportant les dfinitions des mthodes. Il sagit ici dune forme dcriture des classes et non dune entorse au principe dencapsulation (ou denveloppement) car le compilateur rassemble ce qui doit ltre. Dautre part, le principe dabstraction (ou de contrle daccs) est garanti ds lors que sont bien dfinis les degrs de visibilit et que laccs aux attributs nest possible que par les mthodes exposes cet effet. Sans doute davantage un objectif quun principe, la rutilisabilit est une notion indissociable de la POO. Et cest bien la perspective de la rutilisation de classes par divers programmeurs clients qui justifie le contrle daccs. Un autre point dcoule de cette notion : les classes ne doivent pas contenir de codes lis lIHM (interface homme machine). Cette assertion vaut en tous cas pour les classes outils. Bien sr si lobjet dune classe est de dessiner une fleur dans lenvironnement graphique de Windows, alors Mais la plupart des classes sont des outils de description et de rsolution de problmes du monde extrieur, rel ou virtuel. Seules les applications qui exploitent ces classes en vue de produire des solutions globales destination de ce monde ont besoin de dfinir les IHM. Compte tenu des considrations ci-dessus, la structure dune classe et de lapplication qui lexploite devrait toujours tre conforme au schma suivant.

    Les includes des librairies ncessaires

    La fonction principale et les

    autres +

    IHM

    Lapplication en mode texte (Console)

    Les includes des librairies ncessaires

    La fonction principale et les

    autres +

    IHM

    Lapplication en mode graphique

    (Windows)

    Ralisation ou

    Exploitation Les dclarations

    (.h)

    Les dfinitions

    (.cpp)

    Une classe

    Linterface de la classe (ses mthodes public)

    Implmentation

    Ralisation ou

    Exploitation

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 31

    5.4.1. Mise en uvre sous linterface de dveloppement La cration dun nouveau projet C++ sous Visual Studio.Net commence par la dsignation de lemplacement des fichiers en mmoire de masse et par la dnomination du projet. Pour la mise en uvre de la classe MonEntierClass et dune application pour son exploitation, un projet ExploitationMonEntierClass est cr. Lexplorateur de solutions prsente la liste des fichiers dj crs : targetver.h, stdafx.h, stdafx.cpp et ExploitationMonEntierClass.cpp. Contenu du fichier targetver.h :

    #pragma once // Explications diverses ... // ... propos la plateforme minimale requise. #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0600 #endif

    Ce fichier dfinit la version minimale de Windows requise pour lapplication et cela ne prsente gure dintrt dans le cadre de ce cours. Linclusion de ce fichier dans stdafx.h peut tre empche et le fichier peut tre supprim. Contenu du fichier stdafx.h :

    // stdafx.h : fichier Include pour les fichiers Include systme standard, ou les fichiers // Include spcifiques aux projets qui sont utiliss frquemment, et sont rarement modifis #pragma once // Empcher les inclusions // redondantes de ce fichier.

    // Cette directive non standard // peut tre remplace par // lemploi judicieux de ifndef, // en encadrant le contenu du // fichier dentte.

    //#include "targetver.h" // Empcher linclusion de targever.h, comme indiqu ci-dessus //#include // A inclure seulement si usage de tchar, notamment selon le

    // prototype de fonction principale. Par exemple : // conserver si le prototype de la fonction main est : // int _tmain(int argc, _TCHAR* argv[]); // et isoler si pas dusage de tchar dans le code et si le // prototype de la fonction main est : // void main(); ou void main(int argc, char * argv[]); ou // int main(); ou int main(int argc, char * argv[]);

    // TODO : faites rfrence ici aux enttes supplmentaires ncessaires au programme #include // Les E/S, #include // le type string // ... // et toutes les autres librairies communes de nos projets #include #include using namespace std; // Pour viter les agaantes rptitions de std::

    Contenu du fichier stdafx.cpp :

    // stdafx.cpp : fichier source incluant simplement les fichiers Include standard // ExploitationMonEntierClass.pch reprsente l'entte prcompil // stdafx.obj contient les informations de type prcompiles #include "stdafx.h" // TODO : faites rfrence aux enttes supplmentaires ncessaires dans STDAFX.H // absents de ce fichier

    Contenu du fichier UnInclude.h : #ifndef _UnInclude #define _UnInclude // codes ncessaires #endif

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 32

    Le contenu original du fichier ExploitationMonEntierClass.cpp :

    // ExploitationMonEntierClass.cpp : dfinit le point d'entre pour l'application console. #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { return 0; }

    Ce contenu original du fichier ExploitationMonEntierClass.cpp est remplac par :

    #include "stdafx.h" // Placer ici les includes spcifiques lapplication (les classes) // Placer ici les prototypes des ventuelles fonctions secondaires ( dfinir ailleurs) void main() ou { return; }

    A noter ici que sous lenvironnement CodeBlocks, la fonction main() est de type int et se termine donc par le return dun entier (comme en ANSI C). 5.4.2. La cration dune classe et son intgration dans le projet La cration dune classe commence par lintgration de son fichier entte et de son fichier source dans le projet. Dans lexplorateur de solutions, un clic-droit sur Fichiers sources, ou sur Fichiers dentte, ouvre une cascade de menus contextuels conduisant, via Nouvel lment, la bote de dialogue prsente ci-dessous.

    Il convient donc dajouter ainsi un fichier dentte (.h) et un fichier C++ (.cpp), et de les nommer correctement, soit dans le cas de cet exemple :

    MonEntierClass.h MonEntierClass.cpp

    Contenu du fichier MonEntierClass.h : #include "stdafx.h" class MonEntierClass // Dfinition de la classe avec les prototypes de ses mthodes { private : int i; public : int Lit_i(void); void Ecrit_i(int); };

    void main(int argc, char * argv[]){ return; }

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 33

    Contenu du fichier MonEntierClass.cpp : #include "stdafx.h" #include "MonEntierClass.h" // Inclure les dclarations et dfinir les mthodes void MonEntierClass::Ecrit_i(int valeur) { i = valeur; } int MonEntierClass::Lit_i(void) { return i; } Contenu du fichier ExploitationMonEntierClass.cpp complt pour raliser lapplication demande : #include "stdafx.h" #include "MonEntierClass.h" // Linterface de la classe void main() { MonEntierClass E; // Instanciation dun objet E E.Ecrit_i(7); cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 34

    Les nouvelles mthodes sont dfinies dans le fichier MonEntierClass.cpp. void MonEntierClass::Initialisation(int N) {

    i = N; // Initialisation par la valeur du paramtre } void MonEntierClass::Finalisation(void) {

    i = 0; // Sans intrt, sauf pour lexemple } MonEntierClass & MonEntierClass::CloneMoi(void) {

    static MonEntierClass E; // Instancie un nouveau MonEntierClass MonEntierClass & rE = E; // Dfinition dune rfrence pour le retour E.i = this->i; // Copie de mes valeurs vers linstance return rE; // Retour de la rfrence

    } void MonEntierClass::AffecteMoi(MonEntierClass & Cible) {

    Cible.i = this->i; // Copie de mes valeurs vers la cible }

    Le fichier ExploitationMonEntierClass.cpp est modifi pour permettre le test des nouvelles mthodes. #include "stdafx.h" #include "MonEntierClass.h" // Linterface de la classe void main() {

    MonEntierClass E; MonEntierClass F; MonEntierClass & rF = F ; E.Initialisation(17); // Initialisation de la donne de E E.AffecteMoi(rF); // Affectation de E F (rF rfrence F)

    cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 35

    5.6. Une classe bien crite Il sagit maintenant de sintresser aux outils et techniques qui permettent lcriture correcte des classes. La correction de la classe MonEntierClass est une illustration des objectifs atteindre pour obtenir des classes bien crites. Le fichier MonEntierClass.h.

    class MonEntierClass { private : int i; public : MonEntierClass(void); // Constructeur par dfaut MonEntierClass(int); // Au lieu de Initialisation(int); ~MonEntierClass(void); // Au lieu de Finalisation(void);

    MonEntierClass(const MonEntierClass &); // Au lieu de & CloneMoi(void); MonEntierClass &operator=(const MonEntierClass &);// Au lieu de AffecteMoi(); int Lit_i(void); void Ecrit_i(int); };

    Les nouvelles mthodes dfinies dans le fichier MonEntierClass.cpp (Lit_i et Ecrit_i dj crites ne sont plus reproduites ici).

    // Le constructeur par dfaut requis par la forme Coplien MonEntierClass::MonEntierClass(void) {

    i = 0; // Une initialisation par dfaut } // Un constructeur initialisateur (non requis par la forme Coplien) MonEntierClass::MonEntierClass(int N) {

    i = N; // Initialisation par le paramtre du constructeur } // Le destructeur requis par la forme Coplien MonEntierClass::~MonEntierClass(void) {

    i = 0; // Sans intrt, sauf pour lexemple } // Le constructeur par recopie requis par la forme Coplien MonEntierClass::MonEntierClass(const MonEntierClass & Modele) {

    i = Modele.i; // Copie des valeurs du modle vers linstance } // Loprateur d'affectation requis par la forme Coplien MonEntierClass & MonEntierClass::operator=(const MonEntierClass & Source) {

    if (this != &Source) // Vrification indispensable sil sagit dobjets { // dynamiques (ce qui nest pas le cas ici)

    i = Source.i; } return *this; // C'est la cible qui active l'oprateur

    } Le fichier ExploitationMonEntierClass.cpp est modifi pour permettre le test des nouvelles mthodes. #include "stdafx.h" #include "MonEntierClass.h" // Linterface de la classe

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 36 void main() {

    MonEntierClass E(17); // Constructeur avec initialisateur MonEntierClass F; // Constructeur par dfaut MonEntierClass & rE = E; // Une rfrence sur E MonEntierClass & rF = F; // Une rfrence sur F cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 37

    Lintrt du constructeur par dfaut qui initialise un entier zro nest autre quillustratif. Il en est de mme pour le constructeur avec initialisateur. Ce nest bien entendu pas toujours le cas et une nouvelle classe MesEntiers, qui est un vecteur de int, va permettre une illustration en situation relle et ncessaire des outils et techniques abords dans ces pages. Le fichier dentte de la nouvelle classe : MesEntiers.h. #include "stdafx.h" class MesEntiers // Un vecteur d'entiers { private : // int i; // Lindice de balayage du vecteur est dfini l o il est requis int * pI; // Pointeur d'accs au vecteur int Taille; // La taille du vecteur void Copie(MesEntiers &, const MesEntiers &); // Fonction prive, outil de la classe public : MesEntiers(int = 10, int = 0); // Taille et Valeur d'initialisation ~MesEntiers(void); // Destructeur MesEntiers(const MesEntiers &); // Constructeur par recopie MesEntiers &operator=(const MesEntiers &); // Oprateur daffectation int Lit_Taille(void); // Taille du vecteur de l'instance int Lit_Elem(int); // Lire la valeur l'indice donn void Ecrit_Elem(int, int); // Ecrire la valeur l'indice donn }; Les nouvelles mthodes sont dfinies dans le fichier MesEntiers.cpp. Voici les mthodes et outils spcifiques de cette classe. #include "stdafx.h" #include "MesEntiers.h" // Ecrire la valeur V la position I du vecteur, I ne pouvant se situer au-del du vecteur void MesEntiers::Ecrit_Elem(int V, int I) { if (I >= Taille) I = Taille - 1; // Limitation arbitraire anti erreur *(pI + I) = V; } // Lire la valeur la position I du vecteur, I ne pouvant tre au-del du vecteur int MesEntiers::Lit_Elem(int I) { if (I >= Taille) I = Taille - 1; // Limitation arbitraire anti erreur return *(pI + I); } // Permettre lutilisateur de la classe de relire la taille du vecteur int MesEntiers::Lit_Taille(void) { return Taille; } // Fonction prive (car elle nest utile qu cette classe) excutant des codes qui autrement, // seraient crits deux fois dans la classe, une fois dans le constructeur par recopie et une // fois dans loprateur daffectation. Cette fonction copie toutes les valeurs dune instance // Source vers une instance Cible. void MesEntiers::Copie(MesEntiers & Cible, const MesEntiers & Source) { Cible.Taille = Source.Taille; // Toutes les valeurs doivent tre copies for (int i = 0; i < Source.Taille; i++) Cible.pI[i] = Source.pI[i]; } // La dclaration des indices l o ils sont requis permet de rserver lespace de dclaration de // la classe ses seuls membres spcifiques.

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 38 // Les constructeurs de cette classe rservent lespace mmoire pour le stockage dun certain // nombre dentiers par lemploi de la fonction new[]. Il est ds lors impratif de librer cette // mmoire par lusage de la fonction delete []. MesEntiers::~MesEntiers(void) { delete [] pI; // Libration de lespace mmoire } // Le constructeur avec paramtres optionnels permet linstanciation sans paramtre (comme le // font ordinairement les constructeurs par dfaut), mais aussi linstanciation dun vecteur de // la taille souhaite, ce vecteur tant initialis par des 0 ou par une valeur donne. MesEntiers::MesEntiers(int T, int V) // Taille et Valeur d'initialisation { Taille = T; pI = new int[Taille]; // Rservation despace mmoire for (int i = 0; i < Taille; i++) *(pI + i) = V; } // Le constructeur par recopie livre une instance dont toutes les valeurs sont gales celles de // linstance modle. MesEntiers::MesEntiers(const MesEntiers & Modele) { pI = new int[Modele.Taille]; // Rservation despace mmoire // this->Taille = Modele.Taille; // Plac dans Copie() Copie(*this, Modele); } // L'oprateur d'affectation transforme une instance existante en remplaant toutes ses valeurs // par celles dune instance source. Linstance existante est dtruite pour librer la mmoire de // ses valeurs devenues obsoltes. Elle est ensuite reconstruite et reoit alors les valeurs qui // lui sont destines. Cette faon de faire garantit la prsence de 2 objets complets et // distincts lissue du traitement. MesEntiers & MesEntiers::operator=(const MesEntiers & Source) { if (this != &Source) // Car si les objets sont la mme adresse, { // il sagit du mme objet et la destruction delete [] this->pI; // de ses donnes les rendrait irrcuprables this->pI = new int[Source.Taille]; // this->Taille = Source.Taille; // Plac dans Copie() Copie(*this, Source); } return *this; } 5.6.1.1.b. Le destructeur Alors que la classe MonEntierClass prsentait un destructeur purement illustratif, la classe MesEntiers quant elle contient un destructeur absolument ncessaire.

    MonEntierClass::~MonEntierClass(void) // Destructeur de la classe MonEntierClass {

    i = 0; // Sans intrt, sauf pour lexemple } MesEntiers::~MesEntiers(void) // Destructeur de la classe MesEntiers {

    delete [] pI; // Libration de lespace mmoire }

    Il est effectivement impratif de librer la mmoire alloue dynamiquement par new [] par lusage de la fonction approprie delete []. Il faut noter ici que ce destructeur ne doit pas tre explicitement appel dans le code dexploitation de la classe. Il est activ automatiquement par le destructeur commis doffice par le compilateur toute instance de classe, lorsque lexcution de lapplication quitte la porte o est requise cette instance. Lexprience qui consiste placer une instruction de sortie dans le destructeur permet dobserver quil est appel trois fois (une fois pour linstance E, une fois pour F et une fois pour Cop) la fin du programme dexprimentation dcrit ci-aprs.

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 39

    5.6.1.2. Loprateur daffectation Le code dexprimentation, aussi bien celui de MonEntierClass que celui de MesEntiers crit ci-aprs, montre que la surcharge de loprateur produit une fonction qui peut tre employe indiffremment avec la syntaxe dune mthode telle que F.operator=(rE) ou par lemploi de loprateur ordinaire daffection =. Seule cette deuxime possibilit est conserve dans la suite de ces pages. Comme indiqu en commentaire dans le code ci-dessus, linstance destinatrice de laffectation, pour autant quelle soit diffrente de linstance source, est dtruite et reconstruite avant laffectation des valeurs. Outre de garantir la prsence de deux objets complets et distincts lissue du traitement, le procd libre la mmoire qui aurait t occupe par un destinataire plus encombrant. Mais la garantie dobtenir deux objets complets et distincts est bien le principal objectif de la surcharge de loprateur daffectation requise par la forme Coplien. Lexprience suivante peut tre mene sur lexemple de la classe MesEntiers et sur son code dexprimentation. Pour commencer, tout ce qui concerne la surcharge de loprateur daffectation est isol en commentaire dans les fichiers MesEntiers.h et MesEntiers.cpp. Il faut ensuite modifier et exprimenter le code dexploitation comme indiqu ci-aprs. Dans le fichier dentte MesEntiers.h :

    class MesEntiers { // ...

    /* MesEntiers &operator=(const MesEntiers &); */ // ... };

    Dans le fichier dimplmentation MesEntiers.cpp :

    /* MesEntiers & MesEntiers::operator=(const MesEntiers & Source) { // ... } */

    Dans le fichier dexploitation ExploitationMesEntiers.cpp :

    // ... MesEntiers E(15, 7); // Constructeur avec initialisateur (15 positions, valeurs 7) MesEntiers F; // Constructeur par dfaut (10 positions, valeurs 0) cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 40

    Le fichier ExploitationMesEntiers.cpp cr pour permettre les tests de la classe MesEntiers : #include "stdafx.h" #include "MesEntiers.h" void main() { MesEntiers E(15, 7); // Constructeur (15 positions initialises 7) MesEntiers F; // Constructeur par dfaut (10 positions initialises 0) MesEntiers & rE = E; // Une rfrence sur E MesEntiers & rF = F; // Une rfrence sur F cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 41

    5.7. Spcificits diverses du C++ en POO Les techniques POO abordes jusquici, sont celles requises par la forme Coplien. Il sagit des constructeurs, du destructeur et de loprateur daffectation. Leur utilit a t dmontre par ltude des classes MonEntierClass et MesEntiers. Ces exemples ont aussi t loccasion de se familiariser avec la syntaxe C++ propre la POO. Mais dautres techniques, nouvelles ou dj connues, ont leurs particularits dans le cadre de la programmation oriente objet. Il convient de les examiner. Une nouvelle classe MonEntier, trs semblable la classe MonEntierClass utilise prcdemment, va servir de support aux prochaines exprimentations. Voici ses fichiers dentte et dimplmentation de dpart, ainsi quun fichier dexploitation. Leurs modifications sont reproduites ensuite, au fur et mesure des besoins. Le fichier dentte MonEntier.h : class MonEntier { private : int E; public : // Forme Coplien MonEntier(int = 0); ~MonEntier(void); MonEntier(const MonEntier &); MonEntier & operator=(const MonEntier &); // Mthodes spcifiques int Lit_E(void); void Ecrit_E(int); }; Le fichier dimplmentation MonEntier.cpp : MonEntier::MonEntier(int N) // Forme Coplien { E = N; } MonEntier::~MonEntier(void) { ; /* Rien faire */ } // Forme Coplien MonEntier::MonEntier(const MonEntier & Modele) // Forme Coplien { E = Modele.E; } MonEntier & MonEntier::operator=(const MonEntier & Source) // Forme Coplien {

    if (this != &Source) E = Source.E; return *this;

    } int MonEntier::Lit_E(void) // Mthode spcifique { return E; } void MonEntier::Ecrit_E(int Valeur) // Mthode spcifique { E = Valeur; } Les #include ne sont plus reproduits. Il est dfinitivement admis que le fichier dimplmentation dune classe doit commencer par linclusion du fichier dentte de cette classe et que les fichiers dexploitation doivent inclure les enttes des classes quils utilisent.

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 42

    Le fichier dexploitation ExploitationMonEntier.cpp : void main() {

    MonEntier E(17); // Instanciation avec initialisation 17 MonEntier F; // Instanciation avec initialisation 0 // Exprimentations diverses cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 43

    Les lignes suivantes, places dans ExploitationMonEntier.cpp, ralisent lexprimentation :

    // ... cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 44

    Les lignes suivantes, places dans ExploitationMonEntier.cpp, ralisent lexprimentation :

    // ... cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 45 int MonEntier::FctPublique(void)

    { return StaticPublic; } int MonEntier::DonneFctPrive(void) { return FctPrive();

    } // ...

    Les lignes suivantes, places dans ExploitationMonEntier.cpp, ralisent lexprimentation qui montre que la fonction membre static est unique pour toutes les instances de la classe :

    // ... cout

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 46

    5.7.3. Fonctions membres inline Le seul fait de dfinir une fonction lintrieur de la dclaration dune classe en fait une fonction candidate inline, que ce qualificatif soit employ ou non (attention, inline nest quune demande au compilateur, qui peut lexaucer ou pas). Il est par contre convenable de dclarer ces fonctions lors de la dclaration de la classe et de les dfinir en dehors. Dans ce cas, le qualificatif inline est ncessaire la dclaration et ne peut pas tre rpt lors de la dfinition de la fonction. Bien que certains compilateurs acceptent que les dfinitions des fonctions inline soient crites dans le fichier dimplmentation de leur classe dappartenance, cest dans le fichier dentte de la classe quil convient de dfinir ces fonctions. Soit le fichier dentte MonEntier.h :

    class MonEntier { // ... int TestIL_1(int N) // TestIL_1 est candidate inline car elle est { // dfinie dans la dclaration de sa classe

    // ... return ... ;

    }

    inline int TestIL_2(int); // TestIL_2 est candidate inline car sa dclaration // est assortie de la demande inline

    }; La fonction TestIL_2 doit tre dfinie, sans rptition de la demande inline, de prfrence dans ce fichier dentte, mais en dehors de la dclaration de la classe : int TestIL_2(int N) // Dfinition de la fonction TestIL_2, candidate { // inline, en dehors de sa classe dappartenance

    // ... return ... ;

    } 5.7.4. Fonctions membres constantes Le code dune fonction constante ne peut pas modifier les valeurs des membres de sa classe, quils soient private ou public, const ou non. Soit dans le fichier dentte MonEntier.h : int Lit_E(void) const; // const est crit la fin de la dclaration void Ecrit_E(int); // void Ecrit_E(int) const; // interdit car Ecrit_E doit modifier une

    // donne membre

    Et dans le fichier dimplmentation MonEntier.cpp :

    int MonEntierClass::Lit_E(void) const // const est rpt lors de la dfinition. { // Employ ainsi, const devient un lment return E; // distinctif de la signature de la fonction } void MonEntierClass::Ecrit_E(int Valeur) { E = Valeur; }

  • [ phr @ skynet . be ] 09/03/2015 PHR - POO 47

    5.7.5. Initialisation de membres dans les enttes des constructeurs Il est permis en C++ dinitialiser des donnes membres, private ou public, en utilisant lentte du constructeur par lemploi dune liste de valeurs initiales. Lorsque cette possibilit est exploite pour un constructeur, elle doit ltre pour toutes les surcharges du constructeur et aussi pour le constructeur par recopie faute de quoi la donne ne sera initialise que dans certains cas (lorsque cest le bon constructeur qui est invoqu). Par exemple, la dclaration de la classe MonEntier dj utilise prcdemment et modifie pour lexemple, montre trois constructeurs et des nouvelles donnes membres C et D, ainsi quune mthode de lecture dune de ces donnes :

    class MonEntier { private : int E; int C; int D; public : MonEntier(void); // Constructeur non paramtr MonEntier(int); // Constructeur avec initialisateur (pour E) MonEntier(const MonEntier &); // Constructeur par recopie int Lit_C(); // Un accesseur pour au contenu de C

    // ... Voici le contenu du fichier dimplmentation pour ce qui concerne ces modifications :

    MonEntier::MonEntier(void) : C(7), D(77) // Initialisation de C avec la valeur 7 { // et D avec la valeur 77 E = 0; } MonEntier::MonEntier(int N) : C(N) // Initialisation de C av