La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

++ - 1 M. BENJELLOUN : 2005-06 Info II Mohammed BENJELLOUN Service dInformatique Faculté Polytechnique de Mons 2005-2006.

Présentations similaires


Présentation au sujet: "++ - 1 M. BENJELLOUN : 2005-06 Info II Mohammed BENJELLOUN Service dInformatique Faculté Polytechnique de Mons 2005-2006."— Transcription de la présentation:

1

2 M. BENJELLOUN : Info II Mohammed BENJELLOUN Service dInformatique Faculté Polytechnique de Mons Programmation en

3 M. BENJELLOUN : Info II Qu'est-ce qu'un bon programme? INSTANTANE ! Lisible Structuré Portabilité Efficacité Rapidité? Il doit résoudre le PROBLEME ! DUREE DE VIE ?

4 M. BENJELLOUN : Info II Les autres types seront dérivés de ceux-ci. Types de base en C++ TypeReprésentationSignificationIntervalleTaille en octets Exemple caractères signed char ou char unsigned char Un caractère unique-128 à à 'a' 'A' 'Z' '\n' '\t' entiers signed int ou int unsigned int short ou long entier signé (par défaut) entier positif spécifie la taille de l'emplacement mémoire utilisé -231 à 231 –1 0 à à 2 15 –1 2 ou réels float double long double Réel simple précision Réel double précision Réel précision étendue +-10 E-37 à +-10 E E-307 à +-10 E E– sizeof(i) ; retourne la taille en octet de la variable i booléen : bool qui s'accompagne des mots-clés true et false.

5 M. BENJELLOUN : Info II void main(void) { /* corps du programme*/ déclaration des Cstes et Var ; instruction1 ; instruction2 ; …. } Tout programme doit avoir un point dentrée nommé main() main() est la fonction appelée lors de lexécution du programme. { et } délimitent le corps de la fonction, bloc, la succession d'actions à réaliser. Chaque expression (instruction) doit finir par ; Commentaire : texte encadré par les symboles /* et */ ou une ligne commençant par le symbole // Pour commencer void main(void): La fonction main ne prend aucun paramètre et ne retourne pas de valeur. int main(void): La fonction main retourne une valeur entière à l'aide de l'instruction return (0 si pas derreur). main(void) main()

6 M. BENJELLOUN : Info II Variables : déclarations, Syntaxe : Type identificateur1, id2,…. ; char c1, c2, c3; int i, j, var_ent; Exemple: initialisations int i=9; ou int i; i=9; char c1= ' A'; ou char c1; c1= 'A';

7 M. BENJELLOUN : Info II Identificateurs Les identificateurs nomment les objets C++ (fonctions, variables...). Le C++ distingue les minuscules des majuscules. Exemple: abc, Abc, ABC sont des identificateurs valides et tous différents. Identificateurs valides : xx y1 somme_5 _position Noms Programme_1 Identificateurs invalides : 3eme commence par un chiffre x#y caractère non autorisé (#) no-commande caractère non autorisé (-) taux change caractère non autorisé (espace)

8 M. BENJELLOUN : Info II Un identificateur ne peut pas être un mot réservé du langage : asmautoboolbreakcase catchcharclassconstcontinue defaultdeletedodoubleelse enumexternfloatforfriend gotoifinlineintlong mutablenamespacenewoperatorprivate protectedpublicregisterreturnshort signedsizeofstaticstructswitch templatethistypedefunionunsigned usingvirtualvoidvolatilewhile Les mots réservés du langage C++ doivent être écrits en minuscules.

9 M. BENJELLOUN : Info II Les entrées /sorties : cin et cout cout, le flux standard de sortie, habituellement associé à l'écran, Syntaxe : cout << expression << expression << expression … ; cin, le flux standard dentrée, habituellement associé au clavier, Syntaxe : cin >> valeur >> valeur >> valeur … ; cin et cout sont définies dans la librairie. #include void main(void) { cout <<" Salut a vous tous" << endl; cout << " oui tous " ; } endl signifie un saut de ligne

10 M. BENJELLOUN : Info II #include void main () { int n=2; float x= 3.4; char C= 'A' ; cout << " Entier n = "<< n << " ; Entrez un nouveau = " ; cin >> n ; cout << " Float x = "<< x << " ; Entrez un nouveau = " ; cin >> x ; cout << " Char C = "<< C << " ; Entrez un nouveau = " ; cin >> C ; cout << "\n L'entier vaut maintenant : " << n << endl; cout << " Le flottant vaut maintenant :" << x << endl; cout << " Le caractere vaut maintenant :" << C << endl ; } Entier n = 2 ; Entrez un nouveau = 3 Float x = 3.4 ; Entrez un nouveau = 5.67 Char C = A ; Entrez un nouveau = y L'entier vaut maintenant : 3 Le flottant vaut maintenant :5.67 Le caractere vaut maintenant :y int n=2; float x= 3.4; char C= 'A' ; cout << "Entrez n, x et C : "; cin >> n >> x >> C; cout << C << ' ' << x << ' ' << n Entrez n, x et C : V V 9.9 5

11 M. BENJELLOUN : Info II Les variables doivent être déclarées avant leur utilisation dans un début de bloc (juste après{), zone des déclarations: void main(void) { const int Nmax=10; char c; int i, k; c = 'A'; i = 50; K=10; … Cette règle s'applique à tous : char, int, float... est équivalent à void main(void) { const int Nmax=10; char c = 'A'; int i=50, k; k=10; … = opérateur daffectation Les constantes caractères sécrivent entre quottes simples : 'A' 'A' 's' 's' '2' '2' '[''[' Linitialisation des constantes est obligatoire lors de leur déclaration.

12 M. BENJELLOUN : Info II Les opérateurs arithmétiques Le C++ propose les opérateurs suivants : + addition - soustraction * multiplication / division % modulo (reste de la division entière ) % ne peut être utilisé qu'avec des entiers 7.0/2 7/ / /2

13 M. BENJELLOUN : Info II plus grand >=plus grand ou égal ==égal !=différent Le résultat d'une expression logique est un booléen. Il vaut true si elle est vraie et false sinon. Toute valeur non nulle est considérée comme vraie et la valeur nulle comme fausse. ! ! Les opérateurs de comparaison ! == et pas = if( choix = 2 ){ if( choix == 2) { Correction

14 M. BENJELLOUN : Info II Les structures de contrôle Alternative: if-else Itérations: for, while, do-while Rupture de Contrôle: break, continue, return … Choix Multiple: switch-case Bloc 1 dinstructions Bloc 2 dinstructions ouinon Suite du programme ouinon Suite du programme Bloc dinstructions Condition vraie oui non Bloc dinstructions programme Condition vraie Suite du programme programme Condition vraie if-elsewhile do-while

15 M. BENJELLOUN : Info II Les décisions - if else if ( Condition vraie ) { BLOC 1 D'INSTRUCTIONS } else { BLOC 2 D'INSTRUCTIONS } if ( a 70.0) cout << " Alarme "<

16 M. BENJELLOUN : Info II int i = 1; if(i < 0) cout <<" i < 0 \n"; cout 0 \n"; cout <<" alors!! \n"; … Il faut un i > 0 alors!! int i = 1; if(i < 0){ cout <<" i < 0 \n"; cout 0" << endl; } cout <<" alors!! \n"; alors!! Condition vraie Bloc 1 dinstructions oui non

17 M. BENJELLOUN : Info II int i = -1; if(i < 0){ cout <<" i < 0 \n"; cout 0" << endl; } cout <<" alors!! \n"; i < 0 Il faut un i > 0 alors!! int i = -1; if(i < 0){ cout <<" i < 0 \n"; cout 0" << endl; } else { cout <<" alors!! \n"; } i < 0 Il faut un i > 0 Condition vraie Bloc 1 dinstructions oui non Bloc 2 dinstructions

18 M. BENJELLOUN : Info II #include void main() { int i=0; cout << "i = " << i << endl; i++; cout << "i = " << i << endl; i++; cout << "i = " << i << endl; i++; cout << "i = " << i << endl; } Les itérations – for for( init ;(Condition vraie); itération ) { /* liste d'instructions */ } for (i = 0; i <4; i++) { cout << "i = " << i << endl; } for (i = 0; i <4; ) { cout << "i = " << i << endl; i++ ; } i=0 i=1 i=2 i=3

19 M. BENJELLOUN : Info II La boucle TANT QUE... FAIRE... Boucle pré-testée Il s'agit de l'instruction while : tant que (expression vraie) faire{ BLOC D'INSTRUCTIONS } Organigramme: while ( Condition vraie ) { ; /* bloc d'instructions */ ; } Le test se fait d'abord, le bloc d'instructions n'est pas forcément exécuté. Syntaxe: tant que, pas jusquà ce que! ( Boucles ) ouinon Suite du programme Condition vraie Bloc 1 dinstructions

20 M. BENJELLOUN : Info II do while = REPETER … tant que do { ; /* bloc d'instructions */ ; } while ( Condition vraie ); Condition vraie ouinon Bloc dinstructions programme int j = 5; do cout<<"j = "< 0); cout <<"stop\n"; j = 5 j = 4 j = 3 j = 2 j = 1 stop Suite du programme (garantit lexécution au moins une fois) int j = 5; do { cout<<"j = "< 0); cout <<"stop\n";

21 M. BENJELLOUN : Info II switch = AU CAS OU... FAIRE... switch(variable de type char ou int) // au cas où la variable vaut: { case valeur1 :......; // variable=valeur1 : exécutez ce bloc d'instructions ; break; /* L'instruction d'échappement break; permet de quitter la boucle ou l'aiguillage le plus proche.*/ case valeur2: ; // cette valeur2: exécutez ce bloc d'instructions ; break;.. // etc.... default: ; /* aucune des valeurs précédentes: exécuter ce bloc ; d'instructions, pas de "break" ici.*/ } Le bloc "default" n'est pas obligatoire. valeur1, valeur2, …. doivent être des expressions constantes. Linstruction switch correspond à une cascade dinstructions if...else

22 M. BENJELLOUN : Info II char choix; cout << "Ensemble_instruction1 : TAPEZ 1 " << endl; cout << "Ensemble_instruction2 : TAPEZ 2" << endl; cout << "POUR SORTIR : TAPEZ 3 " << endl; cout << " \n\t\t VOTRE CHOIX: " << endl; cin >> choix ; switch(choix){ case '1': cout << "Ensemble_instruction1 : case 1" << endl; break; case '2': cout << "Ensemble_instruction2 : case 2" << endl; break; case '3': cout << " case 3 : FIN DU PROGRAMME...." << endl; break; default : cout << "\nCE CHOIX N'EST PAS PREVU "<< endl; } switch : instruction commode pour les "menus": int choix; switch(choix) { case 1: … ! switch(i) { case 2 * j:.... float f; switch(f) { case 2:....

23 M. BENJELLOUN : Info II Tableaux et Strings Un tableau est une collection de variables de même type, appelées éléments Type Nom_Tableau[dim]; int tab[4]; déclare un tableau de 4 valeurs entières tab[0]tab[1]tab[2]tab[3] const int SIZE = 5; int A[SIZE] // A est un vecteur de 5 entiers float B[5] intA[SIZE] = { 10, 20, 30, 40, 50 }; intpremier[] = { 1, 2, 3, 5, 7, 11, 13 }; char Tab_Char[4] = { 'A', 'C', 'F', 'G' }; intTab[50] = { 0 }; inti = 10; inta[i]; intprimes[]; Déclaration Initialisation Interdiction

24 M. BENJELLOUN : Info II Chaînes de caractères ou String En C++, il y a deux façons pour traiter et manipuler une chaîne de caractères: char Ident[dim]; Initialisation Pour terminer la chaîne, on place en fin de chaîne le caractère nul '\0', de code ASCII 0. Ce caractère est soit ajouté automatiquement par le compilateur, soit introduit par le programmeur, selon les fonctions utilisées. char S[] = {'H','e','l','l','o','\0'}; 'H''e''l' 'o''\0' S[0]S[1]S[2]S[3]S[4]S[5] char S[6] = "Hello"; char S[] = "Le main"; 'L''e'' 'm''a''i''n''\0' Un tableau de char à une dimension : char Ident[dim]; Un type spécial string : string Ident; // Il faut inclure

25 M. BENJELLOUN : Info II Pourquoi utiliser string Ident; plutôt que char Ident[dim]; ? char S1[6] = "Salut", S2[6] = "Hello", S3[12]; S1= S2; S1= "Hooo"; S3=S1+S2; if(S1= =S2) … Interdit string S1 = "Salut", S2 = "Hello", S3; S1= S2; S1= "Hooo"; S3=S1+S2; if(S1= =S2) … Autorisé S1= "Hello" S1= "Hooo" S3= "HoooHello" false

26 M. BENJELLOUN : Info II Fonctions en C++ Fonctions … pourquoi ? void fonction1() { cout<<"\n fonction1 \n"; void fonction2() { cout<<"\n fonction2 \n"; } L'imbrication de fonctions n'est pas autorisée Définition

27 M. BENJELLOUN : Info II #include … void fonct (int a) { a=1 ; } voidmain(void){ int var = 5; fonct (var); cout << var << endl; } 5 #include … int fonct (int a) { a=1 ; return a; } voidmain(void){ int var = 5; var = fonct (var); cout << var << endl; } 1 #include … void fonct (int &a) { a=1 ; } voidmain(void){ int var = 5; fonct (var); cout << var << endl; } 1

28 M. BENJELLOUN : Info II #include using namespace std; int fonc1(int x); void fonc2(int y); int Var_Glob; void main(void) { /* début du bloc de la fonction main*/ int i, j=5, k; // définition des variables locales i = 0 ; j=fonc1(i) ; fonc2(i) ; } // fin du bloc de la fonction main int fonc1( int var){ ….. ; return var ; } void fonc2( int t){ /* Corps de la fonction fonc2 */ ….. ; } Directives du préprocesseur : accès avant la compilation Directives du préprocesseur : accès avant la compilation Déclarations Programme principal Programme principal Définitions des fonctions Définitions des fonctions Structure d'un programme C++

29 M. BENJELLOUN : Info II Passer des tableaux aux fonctions n Les tableaux peuvent être passés comme paramètres d'une fonction. n Ils ne peuvent pas être retournés comme résultat d'une fonction. n La longueur du tableau ne doit pas être définie à la déclaration de la fonction. n Un tableau peut être modifié dans une fonction. Il est passé par référence (adresse) et non par valeur. ! #include … void Modif(int a[]){ a[0] = 5; a[1] = 6; } void main(void){ int p[2] = { 1, 2 }; cout << p[0] << " ; " << p[1]; Modif(p); cout << p[0] << " ; " << p[1]; } 1 ; 2 5 ; 6

30 M. BENJELLOUN : Info II #include … void Modifier(int v); void main(){ int v = 5; Modifier(v); cout << "\nmain: v = " << v; } void Modifier(int v){ v = v *100; cout << "Modifier: v = "<< v; } #include … void Modifier(int *v); void main(){ int v = 5; Modifier(&v); cout << "\nmain: v = " << v; } void Modifier(int *v){ *v = *v *100; cout << "Modifier: *v = "<< *v; } #include … void Modifier(int &v); void main(){ int v = 5; Modifier(v); cout << "\nmain: v = " << v; } void Modifier(int &v){ v = v *100; cout << "Modifier: v = "<< v; } par Valeur Pointeur Référence Appel par valeurs, pointeurs, références ??!! var = 5 var = 500 var = 5 var = 500 Modifier: v = 500 main: v = 5 Modifier: *v = 500 main: v = 500 Modifier: v = 500 main: v = 500

31 M. BENJELLOUN : Info II #include … void affiche (int a, int b) { cout<<"\t i = " << a << " j = " << b << endl; } void echange (int, int); void main () { int i= 5, j=8; affiche (i, j); echange (i, j); affiche (i, j); } void echange (int a, int b) { int tmp; tmp = b; b = a; a = tmp; } void echange (int*, int*); void main () { int i= 5, j=8; affiche (i, j); echange (&i, &j); affiche (i, j); } void echange (int *a, int *b) { int tmp; tmp = *b; *b = *a; *a = tmp; } void echange (int&, int&); void main () { int i= 5, j=8; affiche (i, j); echange (i, j); affiche (i, j); } void echange (int &a, int &b) { int tmp; tmp = b; b = a; a = tmp; } i = 5 j = 8 i = 8 j = 5 i = 5 j = 8 i = 8 j = 5

32 M. BENJELLOUN : Info II #include … int globale; void fonc(int x); void main(void) { inti = 5, j; float f = 2.8, g; d = 3.7; globale =10; cout << " valeur de j= " << j ; cout << "\nglobale = " << globale ; fonc (i); cout << "\nglobale = " << globale ; } void fonc(int v) { double d, f; i++; globale --; } (0) (1) (2) (3) (4) (5) Règles de visibilité des variables // variable globale;; initialisation à // locales à fonc

33 M. BENJELLOUN : Info II #include … int g; void affichage(int un, int deux) { cout << un << " " << deux << " " << g << endl; } #include … int g; void affichage(int un, int deux, int g) { cout << un << " " << deux << " " << g << endl; }

34 M. BENJELLOUN : Info II Allocation dynamique de la mémoire Tableaux réserver plus de places en mémoire que nécessaire. Création dun tableau de taille quelconque l'allocation dynamique #include … void affiche(int T[], int d, char C[]){ for(int i=0; i

35 M. BENJELLOUN : Info II char *C = new char[N]; et Equiv à char *C; C = new char [N]; *C = new char[N];

36 M. BENJELLOUN : Info II Tableau de taille quelconque #include <… void saisie_vect(int Tab[], int n) { int i; for(i=0;i> Tab[i]; } void Affiche(int Tab[], int dim) { int i; for(i=0;i

37 M. BENJELLOUN : Info II Les Structures Une structure est un ensemble de variables (de types éventuellement différents), définissant un nouveau type sous un seul nom. Les structures sont définies en utilisant le mot-clé struct. struct Etudiant { char nom[30], *adresse; int numero; float poids; struct Date D_Nais; }; /* champs ou membres */ struct Date { intjour; intmois; intan; }; Déclarer des instances Une fois la structure définie, les instances peuvent être déclarées. Par abus de langage, on appellera structure une instance de structure struct Date { intjour, mois, an; } hier, demain; struct Date paques, semaine [7] ; Date noël; // pas de struct Date nouvel_an = { 1, 1, 2005 }; Déclaration avant ; Initialisation

38 M. BENJELLOUN : Info II Des structures dans des structures struct Etudiant{ char nom[30]; char *adresse; int numero; float poids struct Date D_Nais; }; Etudiant JD = { "Dupont", "rue de Houdain, 9, 7000 Mons", 102, 60.7, { 15, 10, 1986 } }; struct Date { intjour; intmois; intan; }; struct Date { intjour; intmois; intan; }; Les membres sont accédés par le nom de linstance, suivi de., suivi du nom du membre cout <<"nom = "<< JD.nom; cout <<"\n numero = "<< JD.numero<< endl; cout << " jour de naissance "<

39 M. BENJELLOUN : Info II struct Etudiant{ char nom[30]; char *adresse; int numero; float poids struct Date { intjour; intmois; intan; }; L'imbrication de structures n'est pas autorisée

40 M. BENJELLOUN : Info II #include … struct Article{ char nom[30]; int prix; }; void Affiche(Article AR){ cout << "\n\t Nom = " << AR.nom << " Prix = " << AR.prix; } void main(void) { Article un_article, plus_art[5]; cout > un_article.nom; cout > un_article.prix; Affiche(un_article); for (int i=0; i<5; i++){ cout > plus_art[i].nom; cout > plus_art[i].prix; Affiche(plus_art[i]); } nom1 prix1 nom2 prix2 nom3 prix3 nom4 prix4 … plus_art[0]plus_art[1]plus_art[2]

41 M. BENJELLOUN : Info II #include … struct Article{ char nom[30]; // ou string nom; int prix; }; void Affiche(Article AR){ cout << "\n\t Nom = " << AR.nom << " Prix = " << AR.prix; } void Saisie(Article AR){ cout > AR.nom; cout > AR.prix; } void main(void) { Article un_article; Saisie(un_article); Affiche(un_article); } Entrez le nom : Television Entrez le prix : 300 void Saisie(Article &AR){ Entrez le nom : Television Entrez le prix : 300 Nom = Television Prix = 300 Une structure peut être passée, comme une autre variable, par valeur ou par adresse Passer par valeur nest pas toujours efficace (recopiage à lentrée) Passer par adresse ne nécessite pas de recopiage Nom = Prix =

42 M. BENJELLOUN : Info II #include … struct Article{ char nom[30]; int prix; }; void Saisie(Article &AR){ cout > AR.nom; cout > AR.prix ; } void main(void) { Article T1[5]; for (int i=0; i<5; i++) Saisie(T1[i]); } T1[i]=Nouv(); Article Nouv(){ Article AA; cout > AA.nom; cout > AA.prix; return AA; } Lopération daffectation = peut se faire avec des structures

43 M. BENJELLOUN : Info II NomadresseSexeres1res2…res N Code nom156 rue je ne sais pas, bte 10, … M1015…8A nom233, rue qui nexiste pas, … F1020…19V nom3…M1314…15C nom20…F10 …11D Myne struct Person{ string nom; char *adresse; int res[Nmax]; char code; }; Person Tab[dim_cnst]; Ou Person *Tab; Sexe

44 M. BENJELLOUN : Info II Gestion des fichiers en C++ Pour manipuler un fichier en C++ il faut #include On y trouve essentiellement les classes: ofstream (output file stream) permet décrire les données dans le fichier ; ifstream (input file stream) permet de lire les données du fichier ; Ouverture et fermeture dun fichier : ofstream output; output.open("Res.txt"); ou output.open("c:\\labojeudi\\Res.txt"); Écriture : Lecture : ifstream input ; input.open("Data.txt"); ou input.open("c:\\labojeudi\\Data.txt");

45 M. BENJELLOUN : Info II #include void main() { ofstream Ecri; char Tab1[6]="Hello"; int Tab2[5]={1,2,3,4,5}; Ecri.open("Mon_fichier.txt"); Ecri << "Mes Donnees" << endl; for(int i=0; i<5; i++){ Ecri << Tab1[i] << " " << Tab2[i]<> Tab1[i] >> Tab2[i]; cout << Tab1[i] << " ; " << Tab2[i]<< endl; i++; } Lec.close(); } Mes Donnees H ; 1 e ; 2 l ; 3 l ; 4 o ; 5 ?? Test! ici

46 M. BENJELLOUN : Info II Ecri.open("Mon_fichier.txt"); if(Ecri) { // on vérifie si l'ouverture se passe bien Ecri << "Mes Donnees" << endl; for(int i=0; i<5; i++){ Ecri << Tab1[i] << " " << Tab2[i]<

47 M. BENJELLOUN : Info II un tableau trié + un élément N Nmax N+1Nmax N+1 6 Element ou pas ?? Element Position ?? Recherche dichotomique TEST Et pos

48 M. BENJELLOUN : Info II Recherche dichotomique Et pos N--

49 M. BENJELLOUN : Info II int dicho(struct Element T[], int n, string nom, int &pos); int dicho(struct Element T[], int n, string nom, int &pos) { int debut,fin,m; debut = 0; fin = n; while (debut

50 M. BENJELLOUN : Info II const int NMax = 5; struct Etudiant{ char *nom ; int numero ; int Matieres[NMax] ; } ; void saisie(Element T[], int n, int NM) { … n? NM? … } void affichage( ) { … }

51 M. BENJELLOUN : Info II void saisie(struct Element T[], int &n, int &NM) { int i, j, size; string name; ? n et NM for(i=0;i> T[i].num; for(j=0;j< NM;j++){ … } size = name.length(); ou size = name.size();

52 M. BENJELLOUN : Info II

53 M. BENJELLOUN : Info II struct point { int x ; int y ; } ; Tableaux et structures struct point Sgm[7]; // Sgm[3].y est le champ y de la 4è position : 4 Avantages : Facilité de création et de manipulation (accès à un élément, …) Inconvénients : place mémoire, difficilement extensible, insertion nest possible que par décalage de tous les éléments suivants. struct point Sgm[7]; ou struct Date *Sgm; avec new Sgm[0] Sgm [1] Sgm [2]

54 M. BENJELLOUN : Info II Listes Chaînées Les listes sont des structures de données dynamiques, linéaires. Elles sont composées de cellules chaînées les unes aux autres par pointeurs.

55 M. BENJELLOUN : Info II Une liste chaînée (linked list) est composée de nœuds (node), chacun ayant un pointeur vers le nœud suivant de la liste. Chaque nœud « contient » ou « est » une entité. Ainsi, le nœud A pointe sur le nœud B, le nœud B pointe sur le nœud C, etc., jusqu'au dernier nœud, le E, qui pointe sur NULL. L'avantage ici, c'est que l'on peut faire exécuter la même fonction pour chaque nœud de la liste en n'appelant cette fonction que pour le premier nœud.

56 M. BENJELLOUN : Info II Une liste simplement chaînée : une cellule est un enregistrement qui peut être déclarée comme suit: struct Node { intdata; //les informations struct Node*suiv; // le lien }; struct Node { intdata; //les informations struct Node*suiv; // le lien }; Une liste doublement chaînée struct Node { intdata; // les informations struct Node*suiv; // lien vers le suivant struct Node*prec; // lien vers le précédent }; struct Node { intdata; // les informations struct Node*suiv; // lien vers le suivant struct Node*prec; // lien vers le précédent };

57 M. BENJELLOUN : Info II Une cellule étant une structure qui contient un élément à stocker et un pointeur sur la prochaine cellule de la liste. struct Cellule{ ELEMENT Data;// une structure définie préalablement struct Cellule *suiv; // pointeur sur le prochain maillon }; Modéliser une liste chaînée consiste à allouer dynamiquement les cellules chaque fois que cela est nécessaire. Listes Chaînées Tête Elm1Elm2Elm3Elm4 Liste simplement chaînée

58 M. BENJELLOUN : Info Tête_List Autres Fin_List

59 M. BENJELLOUN : Info Tête_List Liste circulaire

60 M. BENJELLOUN : Info II Initialiser les valeurs de la structure représentant la liste pointée par Debut pour que celle-ci soit vide. Une liste est vide lorsque Tête_List (Fin_List) pointe sur Vide. Les différentes opérations et fonctions typedef struct Cellule{ Type Data; struct Cellule * next; // pointeur sur la prochaine cellule }CEL; CEL *debut; debut = new (CEL); typedef : mot réservé, crée de nouveaux noms de types de données Ex : typedef char * STRING; fait de STRING un synonyme de "char * " Portée : comme les variables. Initialiser une liste

61 M. BENJELLOUN : Info II CEL * new_node(Type value) { CEL * nouv; nouv = new CEL; nouv Data = value; nouv suiv = NULL; return nouv; } Allouer et assigner une Cellule Cette fonction réserve l'espace mémoire nécessaire pour une nouvelle Cellule dans la liste, assigne les données, et retourne un pointeur sur cette Cellule. typedef struct Cellule{ Type Data; struct Cellule * suiv; }CEL; NULL nouv

62 M. BENJELLOUN : Info II typedef struct Cellule{ int Data; }CEL; CEL cel, *Pcel; Cel. Data = 10; Pcel Data = 20;

63 M. BENJELLOUN : Info II Nouvelle cellule dans une liste chaînée vide Si typedef struct Cellule{ string nom; struct Cellule * suiv; }CEL; CEL *debut; debut = new CEL; debut name = "Denis"; debut suiv = NULL; CEL *debut; debut = new CEL; debut name = "Denis"; debut suiv = NULL; Le début de la liste est indiqué par un pointeur indépendant (debut) et la fin par NULL Denis\0 NULL typedef struct Cellule{ Type Data; struct Cellule * suiv; }CEL; debut

64 M. BENJELLOUN : Info II debut NULL CEL *prec; prec = new CEL; prec name= "Claire"; prec suiv = debut; debut = prec; CEL *prec; prec = new CEL; prec name= "Claire"; prec suiv = debut; debut = prec; prec Claire Denis debut Ajouter une nouvelle cellule en tête de liste

66 M. BENJELLOUN : Info II Insérer une nouvelle cellule après la cellule prec Claire debut Denis NULL prec CEL *p; p = new CEL; p name = "Alfred"; p suiv = prec suiv; prec suiv = p; CEL *p; p = new CEL; p name = "Alfred"; p suiv = prec suiv; prec suiv = p; Alfred p Claire Denis NULL prec Alfred p debut OK?

67 M. BENJELLOUN : Info II Que fait ce code ? Claire debut Denis NULL prec Alfred p CEL *p; p = new CEL; p name = "Alfred"; p suiv = prec suiv; prec suiv = p; CEL *p; p = new CEL; p name = "Alfred"; prec suiv = p; p suiv = prec suiv;

68 M. BENJELLOUN : Info II void Affichage (CEL *debut) { while (debut != NULL) { cout << debut name; debut = debut suiv; } void Affichage (CEL *debut) { while (debut != NULL) { cout << debut name; debut = debut suiv; } Claire Denis NULL Alfred debut Que pensez-vous de la fonction Affichage? CEL *p;.. p=Saisie(..); Affichage(..); p=Ajout(..); Affichage(..); …

69 M. BENJELLOUN : Info II Parcourir une liste void parcours (CEL *debut) { CEL *p; p = debut; while ( p != NULL) { cout << p name; p = p suiv; } void parcours (CEL *debut) { CEL *p; p = debut; while ( p != NULL) { cout << p name; p = p suiv; } ClaireDenis NULL Alfred debut debut est un pointeur sur la cellule qui contient le premier élément de la liste Liste identifier par l'adresse de sa première cellule pp p

70 M. BENJELLOUN : Info II void liberation(CEL *L){ if (L) { CEL *tmp = L suiv; delete L; liberation(tmp); } void liberation (CEL *L) { CEL *tmp; while ( L != NULL) { tmp = L; L=L suiv; delete tmp; } Liberation ClaireDenis NULL Alfred tmp Ici gp2

71 M. BENJELLOUN : Info II Liberation Si typedef struct Cellule{ char *nom; struct Cellule * suiv; }CEL; new void liberation (CEL *L){ … delete nom; delete tmp; … } Pour chaque Cellule

72 M. BENJELLOUN : Info II TRI Claire Denis NULL Alfred Claire Denis NULL Alfred 1 2 3

73 M. BENJELLOUN : Info II Claire Denis NULL Alfred TRI 1 Claire 3 Denis NULL 2

74 M. BENJELLOUN : Info II Supprimer une cellule Libérer une cellule Rechercher une cellule Ajouter en queue de liste Retirer la tête de liste … Autres fonctions En résumé, une liste chaînée par pointeurs permet une insertion et une suppression rapide des éléments. Cependant, contrairement au tableau, une liste chaînée interdit un accès direct aux éléments (mis à part la tête et la queue). Si lordre dinsertion et de suppression des éléments dans la liste importe, deux structures de données sont particulièrement adaptées : la pile et la file.

75 M. BENJELLOUN : Info II Une pile est une liste qui respecte la régle dernier arrivé, premier sorti. Cest une structure de données pour laquelle lajout et la suppression dun élément ne sont autorisés quà une seule extrémité, appelée sommet de la pile. Quant on ajoute un élément, celui-ci devient le sommet de la pile. Quant on retire un élément de la pile, on retire toujours le sommet. Pour résumer, le dernier entré/premier sorti liste LIFO (Last In, First Out). Les piles sont souvent commodes pour dé-récursiver un problème. Modéliser une pile consiste à utiliser une liste chaînée en n'utilisant que les opérations ajouterTete et retirerTete. Dans ce cas, on s'aperçoit que le dernier élément entré est toujours le premier élément sorti. PILE [stack, lifo] Modélisation

76 M. BENJELLOUN : Info II Exemples

77 M. BENJELLOUN : Info II Nouv fonction BOOLEEN empilerElement(CEL * p, ELEMENT Nouv) { return (ajouterTete(p, Nouv) ); } Empiler un élément sur une pile Cette fonction empile l'élément Nouv au sommet de la pile pointée par p. Cela revient à ajouter l'élément Nouv en tête de la liste. VRAI est retournée si l'élément a bien été ajouté. Tête Elm1Elm2Elm3

78 M. BENJELLOUN : Info II Cette fonction dépile l'élément au sommet de la pile pointée par p et stocke sa valeur à l'adresse e. Cela revient à récupérer la valeur de l'élément en tête de liste avant de le supprimer de cette dernière. VRAI est retournée si la pile n'est pas déjà vide. fonction BOOLEEN depilerElement(PILE * p, ELEMENT * e) { if ( ! pileVide(*p)) { *e = sommet(*p); return ( retirerTete(p) ) ; } else{ return FAUX; } Il ne faut pas oublier de libérer la mémoire à chaque retrait du sommet de la pile. Dépiler un élément d'une pile Tête Elm1Elm2Elm3Elm1Elm2Elm3Nouv Elm1Elm2Elm3

79 M. BENJELLOUN : Info II LIFO Last-In-First-Out Le dernier élément ajouté dans la liste, est le premier à en sortir. Opérations: Créer la pile, Ajouter un élément (Push), Effacer un élément (Pop), Eliminer la pile. Exemple

80 M. BENJELLOUN : Info II Push(5) debut 5 Push(9) 9 Push(3) 3 NULL debut Push(7) 7 debut Push procédure

81 M. BENJELLOUN : Info II struct NODE *pLifoStart; int Push( int nombre) { NODE *pNew; pNew = new NODE; if( pNew == NULL ) return 0; pNew->nombre = nombre; pNew->next = pLifoStart; pLifoStart = pNew; return 1; }

82 M. BENJELLOUN : Info II Simulation de la factorielle 4! = 4*3! 4 5! = 5*4! 5 1! = 1*0! 1 2! = 2*1! 2 3! = 3*2! 3 5! = ?? 0! = 1 0 while ( num >0 ) { Push( num ); num--; }

83 M. BENJELLOUN : Info II Simulation de la factorielle 4! = 4*3! 4 5! = 5*4! 5 1! = 1*0! 1 2! = 2*1! 2 3! = 3*2! 3 5! = ?? 0! = 1 0 5! = 5 *24 = 120 1! = 1 *1 = 1 2! = 2 *1 = 2 4! = 4 *6 = 24 3! = 3 *2 = 6 LIFO while ( Pop(&temp) ) { fact *= temp; }

84 M. BENJELLOUN : Info II int Pop( int *pNombre ) // == supprimer début de liste { NODE *pTemp; récupérer l'élément en tête de liste avant de le supprimer delete pTemp; return 1; }

85 M. BENJELLOUN : Info II void CalculFact( int num) { int fact = 1; int temp; while ( num >0 ) { Push( num ); num--; } while ( Pop(&temp) ) { fact *= temp; } printf( "La factorielle est %i\n\n", fact); } Les piles sont commodes pour dé-récursiver un problème.

86 M. BENJELLOUN : Info II Une file d'attente est une structure de données pour laquelle lajout et la suppression dun élément ne sont autorisés quaux seules extrémités, appelées la tête et la queue de la file. Les éléments sont ajoutés en queue de file et sont retirés en tête de file. Pour résumer, le premier entré/ le premier sorti liste FIFO (First In, First Out). FILE D'ATTENTE, queue [queue, FiFo] Exemple : Imprimante en réseau

87 M. BENJELLOUN : Info II Jeu de 52 cartes (4 couleurs et 13 puissances). Le jeu est d'abord mélangé pour ensuite être coupé afin de constituer deux tas de 26 cartes Simulation du déroulement d'une partie du jeu de cartes Bataille

88 M. BENJELLOUN : Info II

89 M. BENJELLOUN : Info II 3 joueurs 4

90 M. BENJELLOUN : Info II NULL debut ?

91 M. BENJELLOUN : Info II Listes doublement chaînées struct Node { intdata; // les informations struct Node*prev; // lien vers le précédent struct Node*next; // lien vers le suivant }; struct Node { intdata; // les informations struct Node*prev; // lien vers le précédent struct Node*next; // lien vers le suivant }; data prev next typedef struct Node Cel; Cel *debut, *fin, *act; int dim = sizeof(Cel); debut = (Cel *) malloc(dim); fin = (Cel *) malloc(dim); debut fin

92 M. BENJELLOUN : Info II debut fin NULL debut prev = NULL; debut next = fin; fin prev = debut; NULL fin next = NULL; data prev next

93 M. BENJELLOUN : Info II Déclaration d'une structure comportant Déclaration d'une structure comportant des fonctions membres des fonctions membres struct point { int x ; int y ; } ; initialise pour attribuer des valeurs aux "coordonnées" d'un point ; deplace pour modifier les coordonnées d'un point ; affiche pour afficher un point. Voici comment nous pourrions déclarer notre structure point : Supposons que nous souhaitions associer à la structure trois fonctions : struct point { int x ; // déclaration "classique" des données int y ; // déclaration des fonctions membre (méthodes) void initialise (int, int) ; void deplace (int, int) ; void affiche () ; } ;

94 M. BENJELLOUN : Info II // Définition des fonctions membres du type point #include using namespace std ; void point :: initialise (int abs, int ord) { x = abs ; y = ord ; } void point :: deplace (int dx, int dy) { x += dx ; y += dy ; } void point :: affiche () { cout << "Je suis en " << x << " " << y << "\n" ; } Définition des fonctions membres point::initialise opérateur de "résolution de portée" Il signifie que l'identificateur initialise concerné est celui défini dans point. En l'absence de ce "préfixe" (point::), nous définirions effectivement une fonction nommée initialise(), mais celle-ci ne serait plus associée à point ; il s'agirait d'une fonction "ordinaire" nommée initialise, et non plus de la fonction membre initialise de la structure point.

95 M. BENJELLOUN : Info II void main() { point a, b ; // on peut accéder aux "membre " avec. a.initialise (5, 2) ; a.affiche () ; a.deplace (-2, 4) ; a.affiche () ; b.initialise (1,-1) ; b.affiche () ; } Je suis en 5 2 Je suis en 3 6 Je suis en 1 -1 void point::affiche () { cout << "Je suis en " << x << " " << y << "\n" ; } struct point { int x ; int y ; void initialise (int, int) ; void deplace (int, int) ; void affiche () ; } ;

96 M. BENJELLOUN : Info II struct point { int x ; int y ; void initialise (int, int) ; void deplace (int, int) ; void affiche () ; } ; Tableaux et structures struct point Segm[7]; // Segm[3].y est le champ y de la 4è position : 4 Avantages : Facilité de création et de manipulation (accès à un élément, …) Inconvénients : place mémoire, difficilement extensible, insertion nest possible que par décalage de tous les éléments suivants. struct point Segm[7]; ou struct Date *Segm; avec new struct Personne { int id; string nom; void saisie(); void affiche(); };

97 M. BENJELLOUN : Info II Objet et classe Le fondement de la programmation orientée objet (POO) est de pouvoir protéger certaines données dune structure, doù la nécessité des classe s. La notion de classe donne en fait la Définition d'un objet. En C++ la structure est un cas particulier de la classe. Plus précisément, une classe sera une structure dans laquelle seulement certains membres et/ou fonctions membres seront "publics", c'est-à-dire accessibles "de l'extérieur", les autres membres étant dits "privés".

98 M. BENJELLOUN : Info II struct Client { // Données membres string Nom, Prenom; int Solde; // Déclaration fonctions membres void Saisir (); void Afficher (); bool Etat_Client(); }; class Client { private: // Données membres string Nom, Prenom; int Solde; public: // Déclaration fonctions membres void Saisir (); void Afficher (); bool Etat_Client(); }; Cachées aux fonctions externes Accessibles depuis l'extérieur de la classe La déclaration d'une classe est voisine de celle d'une structure. Il suffit de: remplacer le mot clé struct par le mot clé class, préciser quels sont les membres publics (fonctions ou données) et les membres privés en utilisant les mots clés public et private. Définition d'une classe

99 M. BENJELLOUN : Info II Encapsulation des données Les divers champs d'une structure sont accessibles en n'importe quel endroit du programme. Une opération telle que celle-ci est donc faisable : clientele[0].Solde = 25000; Le solde d'un client peut donc être modifié sans passer par une méthode dont ce serait le but. struct Client { string Nom, Prenom; int Solde; void Saisir (); void Afficher (); bool Etat_Client(); }; Classe avec : private: // Données membres string Nom, Prenom; int Solde; struct Patient { string Nom, Prenom; string maladies; void Saisir (); void Afficher (); bool Etat_Patient(); };

100 M. BENJELLOUN : Info II Encapsulation L'encapsulation est un mécanisme consistant à rassembler les données et les méthodes au sein d'une structure en cachant l'implémentation de l'objet. Cacher l'information contenue dans un objet et de ne proposer que des méthodes de manipulation de cet objet. Ainsi les propriétés contenues dans l'objet seront assurés/validés par les méthodes de l'objet et ne seront plus de la responsabilité de l'utilisateur extérieur. L'utilisateur extérieur ne pourra pas modifier directement l'information et risquer de mettre en péril les propriétés comportementales de l'objet. L'encapsulation permet donc de garantir l'intégrité des données contenues dans l'objet. (masquage des données)

101 M. BENJELLOUN : Info II Que signifient public, private et protected ? public Un membre déclaré public dans une classe peut être accédé par toutes les autres classes et fonctions. private Un membre déclaré private dans une classe ne peut être accédé que par les autres membres de cette même classe. protected Un membre déclaré protected dans une classe ne peut être accédé que par les autres membres de cette même classe ainsi que par les membres des classes dérivées.

102 M. BENJELLOUN : Info II Un membre public d'une classe peut être accédé partout où il est visible ; un membre privé ne peut être accédé que depuis une fonction membre de la classe. class point { private : // déclaration des membres privés int x ; int y ; public : // déclaration des membres publics void initialise (int, int) ; void deplace (int, int) ; void affiche () ; } ; class point { int x ; int y ; public : void initialise (int, int) ; void deplace (int, int) ; void affiche () ; } ; void point::initialise (int abs, int ord) { x = abs ; y = ord ; }

103 M. BENJELLOUN : Info II Un objet Un objet est donc une instanciation dune classe. Un objet est donc une instanciation dune classe. Cet objet possède tous les attributs et toutes les fonctions membres de la classe, mais avec des valeurs dattributs propres à lobjet. Cet objet possède tous les attributs et toutes les fonctions membres de la classe, mais avec des valeurs dattributs propres à lobjet. class Liste { public: int i; string nom; Liste *Suiv; void AffListe(void); }; // pointeur sur le premier élément de la liste Liste *debut=NULL; void main() { point a, b ; …

104 M. BENJELLOUN : Info II void main() { point a, b ; // 2 objets de type point // on peut accéder aux "membre public" avec. a.initialise (5, 2) ; a.affiche () ; a.deplace (-2, 4) ; a.affiche () ; b.initialise (1,-1) ; b.affiche () ; } Je suis en 5 2 Je suis en 3 6 Je suis en 1 -1

105 M. BENJELLOUN : Info II Les mots clés public et private peuvent apparaître à plusieurs reprises dans la définition d'une classe, comme dans cet exemple : class X { private :... public :... private :... } ; Si l'on rend publics tous les membres d'une classe, on obtient l'équivalent d'une structure. Ainsi, ces deux déclarations définissent le même type point : struct point class point { int x ; { public : int y ; int x ; void initialise (...) ; int y ;..... void initialise (...) ; } ;.... } ;

106 M. BENJELLOUN : Info II class vecteur { //définition des attributs, objets float x,y,z; //déclaration des méthodes void saisir(void); void afficher(void); float norme(void); }; void vecteur::afficher(void) { cout<<"["<x; cout >y; cout >z; } float vecteur::norme(void) { float r; r=sqrt(x*x+y*y+z*z); return r; } private?? public??

107 M. BENJELLOUN : Info II class point { int x ; int y ; public : void initialise (int, int) ; void deplace (int, int) ; void affiche () ; } ; void point::initialise (int abs, int ord) { x = abs ; y = ord ; } class point { int x ; int y ; public : void initialise (int abs, int ord){ x = abs ; y = ord ; } void deplace (int, int) ; void affiche () ; } ; meilleure lisibilité du programme.

108 M. BENJELLOUN : Info II #include using namespace std; class CRec { public: int Long; int Larg; }; void main() { CRec Rc1, Rc2; int Surface = 0; Rc1.Long = 30; Rc1.Larg = 24; Rc2.Long = Rc1.Long/2; Rc2.Larg = Rc1.Larg*2; Surface = Rc1.Long * Rc1.Larg; cout << endl << "Surface rectangle 1 = " << Surface; cout << endl << " Surface rectangle 2 = " << Rc2.Long * Rc2.Larg; } #include using namespace std; class CRec { public: int Long; int Larg; int CalcSurf() { return (Long*Larg); } }; void main() { CRec Rc1, Rc2; int Surface = 0; Rc1.Long = 30; Rc1.Larg = 24; Rc2.Long = Rc1.Long/2; Rc2.Larg = Rc1.Larg*2; Surface = Rc1.CalcSurf(); cout << endl << "Surface rectangle 1 = " << Surface; cout << endl << " Surface rectangle 2 = " << Rc2.CalcSurf(); }

109 M. BENJELLOUN : Info II

110 M. BENJELLOUN : Info II Un constructeur est une fonction membre dinitialisation (définie comme les autres fonctions membres) qui sera exécutée automatiquement à chaque création d'un objet. Le constructeur : porte le nom de sa classe, définit l'initialisation d'une instance, appelé implicitement à toute création d'instance, ne peut retourner aucune valeur, (fonction membre non typée même pas void ), peut admettre des arguments qui sont en fait les valeurs dinitialisation des différents champs de la variable. Constructeur et destructeur Il peut y avoir autant de constructeurs que lon veut (tant quils diffèrent par leur nombre et types darguments), ce qui est très intéressant pour initialiser les variables avec différents types; mais il ny a quun seul destructeur par classe ! class point { /* déclaration des membres privés */ int x, y ; public : // déclaration des membres publics point (int, int) ; // constructeur point (float, float) ; // constructeur point () ; // constructeur } ;

111 M. BENJELLOUN : Info II De même, le destructeur est une fonction membre appelée automatiquement au moment de la destruction de l'objet, il : porte le nom de sa classe précédé d'un tilde (~), n'a pas de type de retour (même pas void), définit la "désinitialisation" d'une instance, appelé implicitement à toute disparition d'instance, fonction membre non typée et sans paramètre. mais il ny a quun seul destructeur par classe ! class point { /* déclaration des membres privés */ int x, y ; public : // déclaration des membres publics point () ; // constructeur ~ point (); //prototype du destructeur } ; point ::point () { cout << "In constructeur \n" ; x=0; y = 0; } point :: ~ point () { cout << "In destructeur \n" ; x=0; y = 0; }

112 M. BENJELLOUN : Info II Constructeurs par défaut Point::Point(){ X = 0; X = 0; Y = 0; Y = 0;} Liste::Liste () // Constructeur par défaut { Tete = new noeud ; } Liste::~Liste () // Destructeur { while ( Tete != NULL ) { Courant = Tete ; Tete = Tete->Suiv ; delete Courant ; } Par définition, le constructeur par défaut est : A::A(); // Avec aucun paramètre ! Rôle : il crée une instance non initialisée quand aucun autre constructeur fourni nest applicable. class Liste { public: int i; Liste *Suiv; void AffListe(void); }; // pointeur sur le premier élément de la liste Liste *debut=NULL;

113 M. BENJELLOUN : Info II class Pile { private: noeud * Deb; // sommet de la pile int size; // nombre délément dans la pile public: Pile () // constructeur { Deb = NULL; size = 0; } ~Pile() { clear(); } // Destructeur void clear() { while (Deb != NULL) { noeud * temp = Deb; Deb = Deb->suiv; delete temp; } size = 0; } };

114 M. BENJELLOUN : Info II Comment concevoir le type de classe CLAS de façon que ce programme : void main() { CLAS x; cout << " Salut \n" ; } Fournisse les résultats suivants : Creation Objet Salut Destruction Objet. CLAS :: CLAS () { cout << "Creation Objet \n" ; } CLAS :: ~ CLAS () { cout << "Destruction Objet \n" ; }

115 M. BENJELLOUN : Info II Constructeurs par paramètres Tab:: Tab ( int taille ) // Constructeur { TabElement = new TElement [taille] ; } Tab ::~ Tab () // Destructeur { delete [] TabElement ; } class noeud { public : string nom ; noeud * Suiv ; noeud ( string info, noeud * suiv ) { nom = info ; Suiv = suiv ; } ~noeud () { } }; class CRec { public: int Long; int Larg; CRec( int Lo, int La){ Long = Lo; Larg = La; } };

116 M. BENJELLOUN : Info II class point { /* déclaration des membres privés */ int x, y ; public : // déclaration des membres publics point () ; // constructeur ~ point (); //prototype du destructeur } ; La déclaration suivante convient-elle toujours ? point a ; à partir du moment où un constructeur est défini, il doit pouvoir être appelé (automatiquement) lors de la création de l'objet a. Ici (Ex2), le constructeur a besoin de deux arguments. Ceux-ci doivent obligatoirement être fournis dans notre déclaration, par exemple : point a(2,5) ; Ex1 class point { /* déclaration des membres privés */ int x, y ; public : // déclaration des membres publics point (int, int) ; // constructeur ~ point (); //prototype du destructeur } ; Ex2

117 M. BENJELLOUN : Info II class x { int i,j ; public: x(int, int ) ; } ; x::x(int ii,int jj) {...} void main(void) { x vx1(2,3) ; // ok x vx1= x(3,5) ; // ok x vx ; // déclenche une erreur de compilation.... Le programme ci-dessus déclenche une erreur car à la déclaration de la variable vx, le compilateur recherche une fonction sans paramètres.

118 M. BENJELLOUN : Info II #include using namespace std; class CRec { public: int Long, Larg; CRec (int Lo, int La){ cout << In Constructeur Param<< endl ; Long = Lo; Larg = La; } CRec (){ cout << In Constructeur 0<< endl ; } int CalcSurf() { return (Long*Larg); } }; void main() { CRec Rc1(10,20), Rc2, Rc3; int Surface = 0; Surface = Rc1.CalcSurf(); cout << endl << "Surface rectangle 1 = " << Surface; cout << endl << " Surface rectangle 2 = " << Rc2.CalcSurf(); Rc3.Long = 30; Rc3.Larg = 24; cout << endl << " Surface rectangle 3 = " << Rc3.CalcSurf(); } In Constructeur Param In Constructeur 0 Surface rectangle 1 = 200 Surface rectangle 2 = Surface rectangle 3 = 720 Initialisation et affectation

119 M. BENJELLOUN : Info II #include using namespace std; class CRec { int Long, Larg; public: CRec (int Lo, int La){ cout << In Constructeur Param<< endl ; Long = Lo; Larg = La; } CRec (){ cout << In Constructeur 0<< endl ; } int CalcSurf() { return (Long*Larg); } }; void main() { CRec Rc1(10,20), Rc2, Rc3; int Surface = 0; Surface = Rc1.CalcSurf(); cout << endl << "Surface rectangle 1 = " << Surface; cout << endl << " Surface rectangle 2 = " << Rc2.CalcSurf(); Rc3.Long = 30; Rc3.Larg = 24; cout << endl << " Surface rectangle 2 = " << Rc3.CalcSurf(); } private: Erreur Initialisation et affectation error C2248: 'Long' : cannot access private member declared in class 'CRec'

120 M. BENJELLOUN : Info II Initialisation, affectation dun objet par un autre de la même classe #include using namespace std; class CRec { int Long, Larg; public: CRec (int Lo, int La){ cout << In Constructeur Param<< endl ; Long = Lo; Larg = La; } CRec (){ cout << In Constructeur 0<< endl ; } int CalcSurf() { return (Long*Larg); } }; void main() { CRec Rc1(10,20), Rc2; int Surface = 0; Rc2 = Rc1; Surface = Rc1.CalcSurf(); cout << "\n Surface rectangle 1 = " << Surface; cout << "\n Surface rectangle 2 = " << Rc2.CalcSurf(); Rc1=CRec(5,15); cout << "\n Surface rectangle 1 = " << Rc1.CalcSurf(); CRec Rc3=Rc1; // initialisation CRec Rc4(Rc1); // idem (syntaxe équivalente) cout << "\n Surface rectangle 3 = " << Rc3.CalcSurf(); cout << "\n Surface rectangle 4 = " << Rc4.CalcSurf(); } In Constructeur Param In Constructeur 0 Surface rectangle 1 = 200 Surface rectangle 2 = 200 In Constructeur Param Surface rectangle 1 = 75 Surface rectangle 3 = 75 Surface rectangle 4 = 75 Pas de constructeur

121 M. BENJELLOUN : Info II Constructeurs par défaut et par paramètres Un constructeur par défaut et par paramètres : Un constructeur par défaut et par paramètres : Constructeur possédant des paramètres avec des valeurs de défaut. Constructeur possédant des paramètres avec des valeurs de défaut. class CRec { int Long; int Larg; public: CRec( int Lo=0, int La=0){ Long = Lo; Larg = La; } }; CRec X; // OK CRec Y(1); // OK CRec Z(1,2); // OK constructeur I (0, 1 ou 2 arguments) ICI GP2

122 M. BENJELLOUN : Info II #include using namespace std ; class point { int x, y ; public : point (int abs, int ord) // constructeur ("inline") avec param { x = abs ; y = ord ; cout << "++ Construction d'un point : " << x << " " << y << "\n" ; } ~point () // destructeur ("inline") { cout << "-- Destruction du point : " << x << " " << y << "\n" ; } } ; point a(1,1) ; // instanciation dun objet de classe point void main() { cout << "****** Debut main *****\n" ; point b(10,10) ; // un objet automatique de classe point point c(3,3) ; int i ; for (i=1 ; i<=3 ; i++) { cout << "** Boucle tour numero " << i << "\n" ; point b(i,2*i) ; // objets créés dans un bloc } cout << "****** Fin main ******\n" ; } ++ Construction d'un point : 1 1 ****** Debut main ***** ++ Construction d'un point : Construction d'un point : 3 3 ** Boucle tour numero 1 ++ Construction d'un point : Destruction du point : 1 2 ** Boucle tour numero 2 ++ Construction d'un point : Destruction du point : 2 4 ** Boucle tour numero 3 ++ Construction d'un point : Destruction du point : 3 6 ****** Fin main ****** -- Destruction du point : Destruction du point : ?

123 M. BENJELLOUN : Info II void main() { cout << "****** Debut main *****\n" ; point b(10,10) ; point c(3,3) ; int i ; for (i=1 ; i<=3 ; i++) { cout << "** Boucle tour numero " << i << "\n" ; point b(i,2*i) ; // objets créés dans un bloc } cout << "****** Fin main ******\n" ; } void main() { cout << "****** Debut main *****\n" ; point b(10,10) ; point c(3,3) ; cout << "** Boucle tour numero " << 1 << "\n" ; point b(1,2) ; // objets créés dans un bloc cout << "** Boucle tour numero " << 2 << "\n" ; point b(2,4) ; // objets créés dans un bloc cout << "** Boucle tour numero " << 3 << "\n" ; point b(3,6) ; // objets créés dans un bloc cout << "****** Fin main ******\n" ; } ?

124 M. BENJELLOUN : Info II #include using namespace std ; class test { public : int num ; test (int) ; // déclaration constructeur ~test () ; // déclaration destructeur } ; test::test (int n) // définition constructeur { num = n ; cout << "++ Appel constructeur - num = " << num << "\n" ; } test::~test () // définition destructeur { cout << "-- Appel destructeur - num = " << num << "\n" ; } void fct (int p) { test x(3*p) ; // notez l'expression (non constante) : 3*p } void main() { test a(1) ; for (int i=1 ; i<=2 ; i++) fct(i) ; } ++ Appel constructeur - num = 1 ++ Appel constructeur - num = 3 -- Appel destructeur - num = 3 ++ Appel constructeur - num = 6 -- Appel destructeur - num = 6 -- Appel destructeur - num = 1 void main() { test a(1) ; fct(1) ; fct(2) ; } Sans Prob Param local dans une fonction

125 M. BENJELLOUN : Info II #include using namespace std ; class point { int x, y ; public : point (int abs, int ord) // constructeur ("inline") { x = abs ; y = ord ; cout << "++ Constr. point " << x << " " << y << "\n" ; } ~point () // destructeur ("inline") { cout << "-- Destr. point " << x << " " << y << "\n" ; } } ; void main() { point a(0,0) ; // un objet automatique de classe point a = point (1, 2) ; // un objet temporaire a = point (3, 5) ; // un autre objet temporaire cout << "****** Fin main ******\n" ; } Objet temporaire, affectation ++ Constr. point Constr. point Destr. point Constr. point Destr. point 3 5 ****** Fin main ****** -- Destr. point 3 5

126 M. BENJELLOUN : Info II void main() { point a, b ; // 2 objets de type point // point * C; // C = new point(5,2); // on peut accéder aux "membre public" avec. a.initialise (5, 2) ; a.affiche () ; a.deplace (-2, 4) ; a.affiche () ; b.initialise (1,-1) ; b.affiche () ; } Je suis en 5 2 Je suis en 3 6 Je suis en 1 -1 Création dun objet de type point, par appel dun constructeur à 2 arguments. (*C).affiche(); ou C affiche(); delete C; Objet dynamique

127 M. BENJELLOUN : Info II #include using namespace std ; class point { int x, y ; public : point (int abs, int ord) // constructeur { x=abs ; y=ord ; cout << "++ Appel Constructeur \n" ; } ~point () // destructeur (en fait, inutile ici) { cout << "-- Appel Destructeur \n" ; } } ; void fct (point *) ; // prototype fonction fct void main() { point * adr ; cout << "** Debut main \n" ; adr = new point (3,7) ; // création dynamique d'un objet fct (adr) ; cout << "** Fin main \n" ; } void fct (point * adp) { cout << "** Debut fct \n" ; delete adp ; // destruction de cet objet cout << "** Fin fct \n" ; } ** Debut main ++ Appel Constructeur ** Debut fct -- Appel Destructeur ** Fin fct ** Fin main Objet dynamique

128 M. BENJELLOUN : Info II #include using namespace std ; class demo { int x, y ; public : demo (int abs=1, int ord=0) // constructeur I (0, 1 ou 2 arguments) { x = abs ; y = ord ; cout << "constructeur I : " << x << " " << y << "\n" ; } demo (demo &) ; // constructeur II (par recopie) ~demo () ; // destructeur } ; demo::demo (demo & d) // ou demo::demo (const demo & d) { cout << "constructeur II (recopie) : " << d.x << " " << d.y << "\n" ; x = d.x ; y = d.y ; } demo::~demo () { cout << "destruction : " << x << " " << y << "\n" ; } void fct (demo d, demo * add) { cout << "entrée fct\n" ; delete add ; cout << "sortie fct\n" ; } void main () { cout << "début main\n" ; demo a ; demo b = 2 ; demo c = a ; demo * adr = new demo (3,3) ; fct (a, adr) ; demo d = demo (4,4) ; c = demo (5,5) ; cout << "fin main\n" ; } Quels sont les résultats fournis par lexécution de ce programme? Un constructeur qui sert à créer un objet identique à lobjet reçu en paramètre.

129 M. BENJELLOUN : Info II #include using namespace std ; class demo { int x, y ; public : demo (int abs=1, int ord=0) // constructeur I (0, 1 ou 2 arguments) { x = abs ; y = ord ; cout << "constructeur I : " << x << " " << y << "\n" ; } demo (demo &) ; // constructeur II (par recopie) ~demo () ; // destructeur } ; demo::demo (demo & d) // ou demo::demo (const demo & d) { cout << "constructeur II (recopie) : " << d.x << " " << d.y << "\n" ; x = d.x ; y = d.y ; } demo::~demo () { cout << "destruction : " << x << " " << y << "\n" ; } void fct (demo d, demo * add) { cout << "entree fct\n" ; delete add ; cout << "sortie fct\n" ; } void main () { cout << "debut main\n" ; demo a ; demo b = 2 ; demo c = a ; demo * adr = new demo (3,3) ; fct (a, adr) ; demo d = demo (4,4) ; c = demo (5,5) ; cout << "fin main\n" ; } debut main constructeur I : 1 0 constructeur I : 2 0 constructeur II (recopie) : 1 0 constructeur I : 3 3 constructeur II (recopie) : 1 0 entree fct destruction : 3 3 sortie fct destruction : 1 0 constructeur I : 4 4 constructeur I : 5 5 destruction : 5 5 fin main destruction : 4 4 destruction : 5 5 destruction : 2 0 destruction : 1 0

130 M. BENJELLOUN : Info II Synthèse class MyClass { public: MyClass(char* name, int id); void fct1(int i); // valeur void fct2(int& i); // reference void fct3(const string& s); // const reference.... }; Passage par valeur l'argument est recopié dans le paramètre => l'argument n'est jamais modifié Passage par référence l'argument et le paramètre référencent la même entité => l'argument peut être modifié Passage par const référence l'argument et le paramètre référencent la même entité mais le paramètre ne peut pas être modifié => l'argument n'est jamais modifié

131 M. BENJELLOUN : Info II #include using namespace std ; class point { int x, y ; public : point () ; // constructeur 1 (sans arguments) point (int) ; // constructeur 2 (un argument) point (int, int) ; // constructeur 3 (deux arguments) void affiche () ; // fonction affiche 1 (sans arguments) void affiche (char []) ; // fonction affiche 2 (un argument chaîne) } ; point::point () // constructeur 1 { x = 0 ; y = 0 ; } point::point (int abs) // constructeur 2 { x = y = abs ; } point::point (int abs, int ord) // constructeur 3 { x = abs ; y = ord ; } void point::affiche () // fonction affiche 1 { cout << "Je suis en : " << x << " " << y << "\n" ; } void point::affiche (char message[]) // fonction affiche 2 { cout << message ; affiche () ; } void main() { point a ; // appel constructeur 1 a.affiche () ; // appel fonction affiche 1 point b (5) ; // appel constructeur 2 b.affiche ("Point b - ") ; // appel fonction affiche 2 point c (3, 12) ; // appel constructeur 3 c.affiche ("Hello ---- ") ; // appel fonction affiche 2 } Je suis en : 0 0 Point b - Je suis en : 5 5 Hello ---- Je suis en : 3 12 Une fonction membre peut appeler une autre.

132 M. BENJELLOUN : Info II #include #include // pour la fonction rand using namespace std ; class hasard { int val[10] ; public : hasard (int) ; void affiche () ; } ; hasard::hasard (int max) // constructeur : il tire 10 valeurs au hasard // rappel : rand fournit un entier entre 0 et RAND_MAX { int i ; for (i=0 ; i<10 ; i++) val[i] = double (rand()) / RAND_MAX * max ; } void hasard::affiche () // pour afficher les 10 valeurs { int i ; for (i=0 ; i<10 ; i++) cout << val[i] << " " ; cout << "\n" ; } Le rôle du constructeur ne se limite pas toujours à une initialisation de l'objet. Le travail réalisé par le constructeur peut être beaucoup plus élaboré. Voici un programme exploitant une classe nommée hasard, dans laquelle le constructeur fabrique dix valeurs entières aléatoires qu'il range dans le membre donnée val (ces valeurs sont comprises entre zéro et la valeur qui lui est fournie en argument) : void main() { hasard suite1 (5) ; suite1.affiche () ; hasard suite2 (12) ; suite2.affiche () ; } Un constructeur de valeurs aléatoires

133 M. BENJELLOUN : Info II #include #include // pour la fonction rand using namespace std ; class hasard { int nbval ; // nombre de valeurs int * val ; // pointeur sur les valeurs public : hasard (int, int) ; // constructeur ~hasard () ; // destructeur void affiche () ; } ; hasard::hasard (int nb, int max) { int i ; val = new int [nbval = nb] ; for (i=0 ; i

134 M. BENJELLOUN : Info II Le pointeur spécial dinstance : this Le mot this est un mot réservé contenant ladresse de lobjet courant. Ce pointeur sert, entre autres, à retourner une référence à cet objet pour les appels en cascade. Dans certaines conditions particulières, il est nécessaire de disposer dun moyen de désigner depuis une fonction membre, non pas les données membres, mais linstance elle-même de la classe sur laquelle la méthode membre est appelée. Le mot clé « this » permet de désigner ladresse de linstance sur laquelle la fonction membre a été appelée (utile pour liste chaînées).

135 M. BENJELLOUN : Info II #include using namespace std ; class point { int x, y ; public : point (int abs, int ord) // constructeur ("inline") { x = abs ; y = ord ; cout << "++ Constr. point " << x << " " << y << " a l'adresse : " << this << "\n" ; } ~point () // destructeur ("inline") { cout << "-- Destr. point " << x << " " << y << " a l'adresse : " << this << "\n" ; } } ; void main() { point a(0,0) ; // un objet automatique de classe point a = point (1, 2) ; // un objet temporaire a = point (3, 5) ; // un autre objet temporaire cout << "****** Fin main ******\n" ; } 0bjet temporaire + this ++ Constr. point 0 0 a l'adresse : 0012FF6C ++ Constr. point 1 2 a l'adresse : 0012FF64 -- Destr. point 1 2 a l'adresse : 0012FF64 ++ Constr. point 3 5 a l'adresse : 0012FF5C -- Destr. point 3 5 a l'adresse : 0012FF5C ****** Fin main ****** -- Destr. point 3 5 a l'adresse : 0012FF6C

136 M. BENJELLOUN : Info II #include using namespace std ; class point { int x, y ; public : point (int abs=0, int ord=0) // Un constructeur ("inline") { x=abs; y=ord ; } void affiche () ; // Une fonction affiche } ; void point::affiche () { cout << "Adresse : " << this << " - Coordonnees " << x << " " << y << "\n" ; } main() // Un petit programme d'essai { point a(5), b(3,15) ; a.affiche (); b.affiche (); } Adresse : 006AFDF0 – Coordonnees 5 0 Adresse : 006AFDE8 – Coordonnees 3 15

137 M. BENJELLOUN : Info II Les tableaux dobjets class point { /* déclaration des membres privés */ int x, y ; public : // déclaration des membres publics point () ; // constructeur ~ point (); //prototype du destructeur } ; point courbe[10], *Dcourbe; Dcourbe = new point[30]; Tableau courbe de 10 objets de type point Allocation mémoire pour 30 objets de type point delete [] Dcourbe;

138 M. BENJELLOUN : Info II La déclaration de ce tableau convient-elle ? point Tab[3] ; class point { /* déclaration des membres privés */ int x, y ; public : // déclaration des membres publics point (int, int) ; // constructeur ~ point (); //prototype du destructeur } ; Ex2 Erreur de compilation point Tab[] = { point(1,1), point(4,5), point (7,8) } ; Une des solutions : ??????

139 M. BENJELLOUN : Info II #include using namespace std ; class point { int x, y ; public : point (int abs=0, int ord=0) { x=abs ; y =ord ; cout << "++ Constr. point : " << x << " " << y << "\n" ; } ~point () { cout << "-- Destr. point : " << x << " " << y << "\n" ; } } ; void main() { int n = 3 ; point courbe[5] = { 7, n, 2*n+5, point(1,2) } ; cout << "*** fin programme ***\n" ; } ++ Constr. point : Constr. point : Constr. point : Constr. point : Constr. point : 0 0 *** fin programme *** -- Destr. point : Destr. point : Destr. point : Destr. point : Destr. point : 7 0

140 M. BENJELLOUN : Info II #include using namespace std ; // création d'un patron de fonctions template T min (T a, T b) { if (a < b) return a ; // ou return a < b ? a : b ; else return b ; } void main() { int n=4, p=12 ; float x=2.5, y=3.25 ; char a='A', b='B'; cout << "min (n, p) = " << min (n, p) << "\n" ; // int min(int, int) cout << "min (x, y) = " << min (x, y) << "\n" ; // float min (float, float) cout << "min (a, b) = " << min (a, b) << "\n" ; // char min (char, char) } patron de fonctions min (n, p) = 4 min (x, y) = 2.5 min (a, b) = A

141 M. BENJELLOUN : Info II template void swap(T& x, T& y) { T tmp = x; x = y; y = tmp; } void main() { int i,j; /*...*/ swap(i,j); // Instancie swap pour int float a,b; /*...*/ swap(a,b); // Instancie swap pour float char c,d; /*...*/ swap(c,d); // Instancie swap pour char string s,t; /*...*/ swap(s,t); // Instancie swap pour String }

142 M. BENJELLOUN : Info II #include using namespace std ; // création d'un patron de classe template class point { T x ; T y ; public : point (T abs=0, T ord=0) { x = abs ; y = ord ; } void affiche () ; } ; template void point ::affiche () { cout << "Paire : " << x << " " << y << "\n" ; } void main () { point ai (3, 5) ; ai.affiche () ; point ac ('d', 'y') ; ac.affiche () ; point ad (3.5, 2.3) ; ad.affiche () ; point as ("Salut", " A vous") ; as.affiche () ; } patron de classe T prend la valeur int pour la classe point Paire : 3 5 Paire : d y Paire : Paire : Salut A vous

143 M. BENJELLOUN : Info II #include using namespace std ; class Copain; class Qui { string LeNom; public: void sonnom(string n) { LeNom =n; } friend Copain; // Les fonctions membres de la classe Copain ont ainsi accès // aux attributs privés de la classe Qui. }; class Copain { string nom; public: void sonnom(string n) { nom=n; } void moi() { cout << nom << " "; } void monami(Qui &q) { cout << q. LeNom << " "; // accès au membre private de Qui // si pas de friend Copain; dans Qui // cannot access private member declared in class 'Qui' } }; void main() { Qui QQui; Copain Cop; QQui.sonnom("Laurel"); Cop.sonnom("Hardy"); Cop.moi(); cout << "est l'ami de "; Cop.monami(QQui); cout << endl; } Hardy est l'ami de Laurel friend Classe amie

144 M. BENJELLOUN : Info II La réutilisation L'héritage est un principe propre à la programmation orientée objet, permettant de créer une nouvelle classe à partir d'une classe existante. Lhéritage Il est possible de représenter sous forme de hiérarchie de classes, parfois appelée arborescence de classes, la relation de parenté qui existe entre les différentes classes. L'arborescence commence par une classe générale appelée superclasse (parfois classe de base, classe parent, classe mère ou père). Puis les classes dérivées (classe fille ou sous-classe) deviennent de plus en plus spécialisées. Ainsi, on peut généralement exprimer la relation qui lie une classe fille à sa mère par la phrase "est un". Un omnivore est un animal mais pas forcement linverse Permet lextension d'une classe de base afin de lui ajouter des fonctionnalités particulières tout en conservant les fonctionnalités déjà définies dans la classe de base.

145 M. BENJELLOUN : Info II Principe de lhéritage Les classes dérivées sont un mécanisme simple pour définir une nouvelle classe en ajoutant des facilités à une classe existante sans reprogrammer ou recompiler la classe de base. On peut ainsi utiliser lhéritage pour les besoins de généralisation, de réutilisation. La classe dérivée hérite des attributs et des fonctions de la classe de base. La classe dérivée est plus spécifique que la classe en ajoutant des attributs et des fonctions membres. En C++, il existe lhéritage simple, et lhéritage multiple. Dans ce cours, nous ne nous intéresserons quà lhéritage simple. Dans la définition de la classe dérivée, afin dutiliser lhéritage, on ajoute le symbole : après le nom de la classe en précisant par la suite quelle est la classe de base. Ex: class ClasseDerivee : public ClasseBase {...}

146 M. BENJELLOUN : Info II class Personne { public: Personne(string nom){…} … }; class Travailleur : public Personne { public: … }; class Employeur : public Personne {... }; class Enfant : public Personne { … };.. class Vehicule { … }; class voiture : public Vehicule { public: //... }; On mentionne cette relation de plusieurs manières: voiture est une sorte de Vehicule voiture est "dérivée de" Vehicule voiture est un Vehicule spécialisé. voiture est une "sous-classe" de Vehicule Vehicule est une "classe de base" de voiture Vehicule est la "superclasse" de voiture Comment exprime t-on l'héritage en C++?

147 M. BENJELLOUN : Info II Mode de dérivation Lors de la définition de la classe dérivée il est possible de spécifier le mode de dérivation par l'emploi d'un des mots-clé suivants : public, protected ou private. Ce mode de dérivation détermine quels membres de la classe de base sont accessibles dans la classe dérivée. Par défaut, le type dhéritage est privé (par défaut le mot-clé private.) Les membres privés de la classe de base ne sont jamais accessibles par les membres des classes dérivées. class ClasseDerivee : Mode ClasseBase {...}

148 M. BENJELLOUN : Info II class CptBanque { int ident; float solde; public: CptBanque(int id, float so = 0); void deposer(float); void retirer(float); float getSolde(); }; public class CptPlus : public CptBanque { float prelev; public: void prelever(); CptPlus(int id, float pr, float so); }; La classe CptPlus est un CptBanque avec de nouvelles fonctionnalités (un prélèvement automatique). Elle hérite des champs et méthodes de CptBanque et possède en plus un champ prelev et de la méthode prelever. Qualifier la classe CptPlus comme héritant public de CptBanque, signifie que tous les champs et méthodes public de la classe CompteBanque (classe de base) sont définis implicitement public dans la classe ComptePrelevementAuto (classe dérivée public). héritage simple public Héritage Public: Les types dattributs C'est la forme la plus courante d'héritage

149 M. BENJELLOUN : Info II Héritage Public: Les types dattributs C'est la forme la plus courante d'héritage Classe de baseClasse dérivée private private protected protected public public Les attributs private, protected et public de la classe de base restent les mêmes pour la classe dérivée. Le type dattribut protected est le plus utilisé lors de lhéritage. class ClasseDerivee : public ClasseBase class Vehicule { public: void pub1(); protected: void prot1(); private: void priv1(); }; class Voiture : public Vehicule { public: int pub2() { pub1(); // OK prot1(); // OK priv1(); // ERREUR } }; Voiture X; X.pub1(); // OK X.pub2(); // OK protégés (protected), c'est à dire accessibles aux membres de la classe et ses classes dérivées (par héritage);

150 M. BENJELLOUN : Info II Il permet de modéliser les relations "Y est composé de un ou plusieurs X". Plutôt que d'hériter de façon privée de la classe de base X, on peut faire de la classe de base une donnée membre (composition). class TXT { public: int length(); //... }; class Dim : private TXT { void f1() { //... l = length(); // OK }; Dim ObjtDim; cout << ObjtDim.length(); // ERREUR Classe de base Classe dérivée private private protected private public private Tous les attributs de la classe de base deviennent private pour la classe dérivée. Héritage Privé: Les types dattributs

151 M. BENJELLOUN : Info II Il peut être intéressant d'avoir des données d'une classe qui soient privés en dehors d'utilisation de l'héritage mais publics dans une chaîne d'héritage. les données protégés (protected). class TXT { protected: int n; }; class Dim : protected TXT { protected: void f2() { n++; } // OK }; class Dim_number : public Dim { protected: void f3() { n++; } // OK }; Classe de base Classe dérivée private private protected protected public protected Les attributs public de la classe de base deviennent protégés pour la classe dérivée. Héritage Protégé: Les types dattributs

152 M. BENJELLOUN : Info II mode de dérivation Statut dans la classe de base Statut dans la classe dérivée public protected privateinaccessible protected publicprotected privateinaccessible private publicprivate protectedprivate inaccessible

153 M. BENJELLOUN : Info II REDEFINITION DE METHODES DANS LA CLASSE DERIVEE Les méthodes (fonctions, …) de la classe de base peuvent être redéfinies dans la classe dérivée (le même nom que dans la classe de base). Elles demeurent accessibles via l'opérateur de résolution de portée ("::"). #include using namespace std; class X { public: void f1(){ cout << "\n In F1 X"; } void f2(){ cout << "\n In F2 X"; } protected: int xxx; }; class Y : public X { public: void f2() { cout << "\n In F2 Y"; } void f3(); }; void Y::f3() { f1(); // appel de f1 de la classe X f2(); // appel de f2 de la classe Y X::f2(); // f2 de la classe X X::xxx = 5; // accès au membre xxx de la classe X cout << "\n In F3 xxx =" << xxx; xxx = 14; // accès au membre xxx de la classe X cout << "\n In F3 xxx =" << xxx; } void main() { X A; Y B; A.f2(); B.f3(); } In F2 X In F1 X In F2 Y In F2 X In F3 xxx =5 In F3 xxx =14

154 M. BENJELLOUN : Info II /* --- Déclaration et définition de la classe pointcol */ class pointcol : public point // pointcol dérive de point { int couleur ; public : void colore (int cl) { couleur = cl; cout << "\n couleur = " << couleur << "\n" ; } } ; void main() { pointcol p ; p.initialise (10,20) ; p.colore (5) ; p.affiche () ; p.deplace (2,4) ; p.affiche () ; } #include using namespace std ; // Déclaration de la classe point class point { /* déclaration des membres privés */ private : int x ; int y ; /* déclaration des membres publics */ public : void initialise (int, int) ; void deplace (int, int) ; void affiche () ; } ; //Définition des fonctions membres de la classe point void point::initialise (int abs, int ord) { x = abs ; y = ord ; } void point::deplace (int dx, int dy) { x = x + dx ; y = y + dy ; } void point::affiche () { cout << "Je suis en " << x << " " << y << "\n" ; } Les membres publics de la classe de base (point) seront des membres publics de la classe dérivée (pointcol). couleur = 5 Je suis en Je suis en 12 24

155 M. BENJELLOUN : Info II class pointcol : public point // pointcol dérive de point { int couleur ; public : void colore (int cl) { couleur = cl; cout << "\n couleur = " << couleur << "\n" ; } } ; void main() { point A; pointcol B; A.initialise (5,10); A.affiche () ; B.initialise (20,30); B.affiche () ; A=B; A.affiche () ; B.affiche () ; } #include using namespace std ; class point { /* déclaration des membres privés */ private : int x ; int y ; /* déclaration des membres publics */ public : void initialise (int, int) ; void deplace (int, int) ; void affiche () ; } ; void point::initialise (int abs, int ord) { x = abs ; y = ord ; } void point::deplace (int dx, int dy) { x = x + dx ; y = y + dy ; } void point::affiche () { cout << "Je suis en " << x << " " << y << "\n" ; } Je suis en 5 10 Je suis en Conversions automatiques : si B hérite de A, alors toutes les instances de B sont aussi des instances de A, et il est donc possible de faire : A a; B b; a=b;

156 M. BENJELLOUN : Info II #include point.h #include " point.h " /* déclaration de la classe point (nécessaire */ /* pour compiler la définition de pointcol) */ using namespace std ; class pointcol : public point { int couleur ; public : void colore (int cl) { couleur = cl ; } void affichec () ; void initialisec (int, int, int) ; } ; void pointcol::affichec () { affiche () ; cout << " et ma couleur est : " << couleur << "\n" ; } void pointcol::initialisec (int abs, int ord, int cl) { initialise (abs, ord) ; couleur = cl ; } void main() { pointcol p ; p.initialisec (10,20, 5) ; p.affichec () ; p.affiche () ; p.deplace (2,4) ; p.affichec () ; p.colore (2) ; p.affichec () ; } Utilisation de pointcol Je suis en et ma couleur est : 5 Je suis en Je suis en et ma couleur est : 5 Je suis en et ma couleur est : 2

157 M. BENJELLOUN : Info II #include using namespace std ; class point { int x, y ; public : point (int abs=0, int ord=0) // constructeur de point ("inline") { cout << "++ constr. point : " << abs << " " << ord << "\n" ; x = abs ; y =ord ; } } ; class pointcol : public point { int couleur ; public : pointcol (int, int, int) ; // déclaration constructeur pointcol } ; pointcol::pointcol (int abs=0, int ord=0, int cl=1) { cout << "++ constr. pointcol : " << abs << " " << ord << " " << cl << "\n" ; couleur = cl ; } void main() { pointcol a(10,15,3); } héritage Constructeurs ++ constr. point : constr. pointcol :

158 M. BENJELLOUN : Info II #include using namespace std ; class point { int x, y ; public : point (int abs=0, int ord=0) // constructeur de point ("inline") { cout << "++ constr. point : " << abs << " " << ord << "\n" ; x = abs ; y =ord ; } } ; class pointcol : public point { int couleur ; public : pointcol (int, int, int) ; // déclaration constructeur pointcol } ; pointcol::pointcol (int abs=0, int ord=0, int cl=1) : point (abs, ord) { cout << "++ constr. pointcol : " << abs << " " << ord << " " << cl << "\n" ; couleur = cl ; } void main() { pointcol a(10,15,3); } héritage Constructeurs ++ constr. point : constr. pointcol :

159 M. BENJELLOUN : Info II héritage Constructeurs et destructeurs #include using namespace std ; class point { int x, y ; public : point (int abs=0, int ord=0) // constructeur de point ("inline") { cout << "++ constr. point : " << abs << " " << ord << "\n" ; x = abs ; y =ord ; } ~point () // destructeur de point ("inline") { cout << "-- destr. point : " << x << " " << y << "\n" ; } } ; class pointcol : public point { int couleur ; public : pointcol (int, int, int) ; // déclaration constructeur pointcol ~pointcol () // destructeur de pointcol ("inline") { cout << "-- dest. pointcol - couleur : " << couleur << "\n" ; } } ; pointcol::pointcol (int abs=0, int ord=0, int cl=1) : point (abs, ord) { cout << "++ constr. pointcol : " << abs << " " << ord << " " << cl << "\n" ; couleur = cl ; } void main() { pointcol a(10,15,3) ; // objets pointcol b (2,3) ; // automatiques pointcol c (12) ; //..... pointcol * adr ; adr = new pointcol (12,25) ; // objet dynamique delete adr ; } ++ constr. point : constr. pointcol : constr. point : constr. pointcol : constr. point : constr. pointcol : constr. point : constr. pointcol : dest. pointcol - couleur : 1 -- destr. point : dest. pointcol - couleur : 1 -- destr. point : dest. pointcol - couleur : 1 -- destr. point : dest. pointcol - couleur : 3 -- destr. point : 10 15

160 M. BENJELLOUN : Info II // classe de base pour liste chaînée template class List { public : List() { Deb=NULL;} ~List(); void insertElem(Elem *); void sort(); private : Elem * Deb; }; //classe dérivée pour liste circulaire template class CycleList : public List { //... public : CycleList(); ~CycleList(); void insertElem(Elem *); void sort(); //... } //Utilisation void main() { List liste; CycleList cListe; //... } Template et héritage : Classe CycleList dérivée du modèle List

161 M. BENJELLOUN : Info II Qu'est ce que la "STL"? La STL ("Standard Templates Library") est une librairie qui est constituée principalement par des classes containers (Conteneurs :collections d'objets ; très efficace), ainsi que des fonctionnalités pour parcourir (iterator) leur contenu et des algorithmes pour travailler sur leur contenu. STL : C++ Algorithms C++ Vectors C++ Double-Ended Queues C++ Lists C++ Priority Queues C++ Queues C++ Stacks C++ Sets C++ Multisets C++ Maps C++ Multimaps C++ Bitsets Iterators STL

162 M. BENJELLOUN : Info II C++ Lists : Container constructorscreate lists and initialize them with some data Container operatorsassign and compare lists assignassign elements to a list beginreturns an iterator to the beginning of the list clearremoves all elements from the list emptytrue if the list has no elements end returns an iterator just past the last element of a list eraseremoves elements from a list insertinserts elements into the list pop_backremoves the last element of a list pop_frontremoves the first element of the list push_backadd an element to the end of the list push_frontadd an element to the front of the list removeremoves elements from a list remove_ifremoves elements conditionally sortsorts a list into ascending order splicemerge two lists in constant time swapswap the contents of this list with another

163 M. BENJELLOUN : Info II #include using namespace std; void main() { //creer une liste (fifo) list listInt; //rajouter des valeurs a la fin de la liste listInt.push_back(33); listInt.push_back(10); //afficher et enlever des valeurs au debut de la liste cout <

164 M. BENJELLOUN : Info II #include using namespace std; void main() { int MAX=10; //créer un vecteur qui stocke MAX entiers vector vecInt(MAX); //remplir vecteur for (int i=0; i=0; i--) { cout <

165 M. BENJELLOUN : Info II #include using namespace std; void main(){ map > age; // age est une map de string à int age["Fred"] = 42; // Fred a 42 ans de age["Barney"] = 37; // Barney a 37 ans ++age["Fred"]; // incrémente l'âge de Fred. cout << "Fred a " << age["Fred"] << " an(s)\n"; --age["Barney"]; cout << "Barney a " << age["Barney"] << " an(s)\n"; }

166 M. BENJELLOUN : Info II void main() { MyMap ListeMap;// Liste MyMap :: iterator my_it;// iterateur char buffer[5]; ListeMap["Mary"] = ; // Mary est un string ListeMap["Mary"] = ; // Le numéro de Mary a changé // Inserser en utilisant la fonction insert : TRi croissant ListeMap.insert( MyMap :: value_type( "Xavier", 777 ) ); ListeMap.insert( MyMap :: value_type( "Chuck", ) ); ListeMap.insert( MyMap :: value_type( "James Bond", 007 ) ); ListeMap.insert( MyMap :: value_type( "Rob", 666 ) ); ListeMap.insert( MyMap :: value_type( "Xavier", 777 ) ); ListeMap.insert( MyMap :: value_type( "Chuck", ) ); // Parcourir et afficher la liste for( my_it = ListeMap.begin(); my_it != ListeMap.end(); my_it++ ) cout << (*my_it).first << " " << (*my_it).second << endl; // Effacer la liste de la mémoire ListeMap.erase(ListeMap.begin(), ListeMap.end()); cout << "\n FIN \n"; } #pragma warning(disable: 4786) #include #include // Pour STL type map using namespace std; typedef map MyMap; Chuck James Bond 7 Mary Rob 666 Xavier 777 FIN

168 M. BENJELLOUN : Info II nom0 9 nom1 1 nom2 6 nom3 3 … TAB[0]TAB[1] void main(){ struct Personne TAB[dim]; } TAB[2] struct Personne { int id; string nom; void saisie(); void affiche(); };

169 M. BENJELLOUN : Info II 1 : Saisie et Affichage 2 : Ajouter au (début, milieu ou fin) et Affichage 3 : Supprimer le début et Affichage 4 : Tri selon NOM et Affichage 5 : Tri selon Id et Affichage 6 : Quitter Menu Elm1Elm2 Elm 1 Elm 5Elm 2Elm 1 Elm5Elm 3 Elm 5Elm 2Elm 1 1 : 2 : 3 : Elm 5Elm 2Elm 1 struct Personne { int id; string nom; void saisie(); void affiche(); };

170 M. BENJELLOUN : Info II void main() { struct Element Tab_Elem[MAX]; int rep_menu, n; do{ rep_menu=menu(); switch(rep_menu) { case 1: Saisie(…); Affichage(…); break; case 2: Ajouter(…);Affichage(…); break; case 3: Effacer(…);Affichage(…); break; case 4: triabulle_nom(…);Affichage(…); break; case 5: triabulle_Code(…);Affichage(…); break; case 6: cout <<"\n\n Fin du Programme \n\n"; break; default : cout<<" Il faut choisir entre 1).... et 6) \n"; } }while (rep_menu!=6); }

171 M. BENJELLOUN : Info II struct Personne { int id; string nom; void saisie(); void affiche(); }; void Personne :: saisie () { cout << "donnez un identifiant"<< endl; cin >> id; cout << "donnez un nom"<< endl; cin >> nom; } ListePersonnes *insereTete(Personne X, ListePersonnes *Tete) { ListePersonnes *nouveau=new ListePersonnes; // création du nouveau noeud nouveau->Element.id=X.id; nouveau->Element.nom=X.nom; nouveau->pNext=Tete; // positionnement en tete-chainage return nouveau; // retour de la nouvelle position } struct ListePersonnes { Personne Element; ListePersonnes *pNext; }; + Classes


Télécharger ppt "++ - 1 M. BENJELLOUN : 2005-06 Info II Mohammed BENJELLOUN Service dInformatique Faculté Polytechnique de Mons 2005-2006."

Présentations similaires


Annonces Google