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

HistoriqueHistorique 1985 1985 Langage C++, parution du livre Bjarne Stroustrup 1998 Normalisation ANSI.

Présentations similaires


Présentation au sujet: "HistoriqueHistorique 1985 1985 Langage C++, parution du livre Bjarne Stroustrup 1998 Normalisation ANSI."— Transcription de la présentation:

1

2 HistoriqueHistorique 1985 1985 Langage C++, parution du livre Bjarne Stroustrup http://www.research.att.com/~bs/homepage.html 1998 Normalisation ANSI du langage C++ 1998 Normalisation ANSI du langage C++ Livre de cours : Programmer en C++,Claude Delannoy Livre de cours : Programmer en C++,Claude DelannoyEyrolles

3 Chapitre 1 Spécificités du Langage C++

4 Spécificité du langage Les variables déclarées constantes const int i = 5; const int i = 5; La variable i ne peut pas être modifiée. int * const ip = &i; int * const ip = &i; La variable ip ne peut pas être modifiée, mais son contenu *ip = 8 oui. const int * ip = &i ; const int * ip = &i ; La variable ip = &j peut être modifiée mais son contenu *ip ne peut pas être modifié. const int * const ip = &i; const int * const ip = &i; ip et *ip ne peuvent pas être modifieés ip et *ip ne peuvent pas être modifieés

5 Spécificité du langage La notion de référence. int i = 5 ; int i = 5 ; int &j = i ; int &j = i ; j est une référence sur i cela veut dire que la variable i a deux noms i et j const int i = 5; const int i = 5; On ne peut pas définir une référence sur une variable déclarée constante. On ne peut pas définir une référence sur une variable déclarée constante. int & j = i; ou int & j = 2 ; ===> erreur du compilateur. int & j = i; ou int & j = 2 ; ===> erreur du compilateur. Par contre on peut déclarer constante la référence: Par contre on peut déclarer constante la référence: const int & j = i ;

6 Spécificité du langage Prototypage Obligatoire Il faut mettre en début de programme la liste des prototypes de fonctions appelées Il faut mettre en début de programme la liste des prototypes de fonctions appelées Exemple : #include int main () Exemple : #include int main () { float AireRectangle(float,float); float Longueur = 10.; float AireRectangle(float,float); float Longueur = 10.; float Largeur=5.; float Largeur=5.; float Aire = AireRectangle(Longueur,Largeur); } float Aire = AireRectangle(Longueur,Largeur); } float AireRectangle(float L, floatl ) { …

7  b  a  b Spécificité du langage Passage des arguments par valeur. Spécificité du langage Passage des arguments par valeur. Exemple : #include void Echange (int a, int b) { int c; c=a; a=b; b=c; } int main() { void Echange (int, int ); Exemple : #include void Echange (int a, int b) { int c; c=a; a=b; b=c; } int main() { void Echange (int, int ); int A, B; A=1; B=2; Echange (A,B); cout << “ A = “ << A << “ B = “ << B << endl; } int A, B; A=1; B=2; Echange (A,B); cout << “ A = “ << A << “ B = “ << B << endl; } A=1, B=2  A  B  b  a  b

8 Spécificité du langage Passage des arguments par adresse. Exemple : #include void Echange (int * ap, int * bp) { int c; c=*ap; *ap=*bp; *bp=c; } int main() { void Echange (int *, int *) int A, B; A=1; B=2; Echange (&A,&B); cout void Echange (int * ap, int * bp) { int c; c=*ap; *ap=*bp; *bp=c; } int main() { void Echange (int *, int *) int A, B; A=1; B=2; Echange (&A,&B); cout << “ A = “ << A << “ B = “ << B << endl; } BAB2 A1 B2 A1 &A B 2 A 1 B 2 A 1 &B &A B 2 A 1 B 2 A 1 &B apbp &A B 2 A 1 B 2 A 1 &B apbp c &A B 2 A 1 B 1 A 2 &B apbp c1 &A B 2 A 1 B 1 A 2 &B A=2, B=1

9 Spécificité du langage Passage des arguments par référence. #include #include namespace std ; namespace std ; void Echange (int & a, int & b) { int c; c=a; a=b; b=c; } void Echange (int & a, int & b) { int c; c=a; a=b; b=c; } int main() int main() { void Echange (int &, int & ) { void Echange (int &, int & ) int A, B; A=1; B=2; Echange (A,B); cout << “ A = “ << A << “ B = “ << B << endl; } int A, B; A=1; B=2; Echange (A,B); cout << “ A = “ << A << “ B = “ << B << endl; } c1 A=2, B=1  A  B  b  A  B

10 Spécificité du langage Problème du passage des arguments Si un argument est passé par valeur : Si un argument est passé par valeur : la fonction travaille sur une copie, la variable passée est protégée donc en mode IN la fonction travaille sur une copie, la variable passée est protégée donc en mode IN Si un argument est passé par référence : Si un argument est passé par référence : la fonction travaille sur la variable sans recopie, la variable passée n’ est pas protégée donc en mode OUT. Si on veut éviter une recopie de l’argument et protéger sa valeur : on utilise le qualificatif const Si on veut éviter une recopie de l’argument et protéger sa valeur : on utilise le qualificatif const Exemple: Fonction ( const int & ) Exemple: Fonction ( const int & )

11 Spécificité du langage Valeurs des arguments d’une fonction par défaut. On peut donner des valeurs par défaut aux arguments d’une fonction au niveau de son prototype: On peut donner des valeurs par défaut aux arguments d’une fonction au niveau de son prototype: int main () { void AireRectangle ( float = 1, float = 1 ) ; void AireRectangle ( float = 1, float = 1 ) ; // Appel de la fonction avec les arguments par défaut. AireRectangle ( ); // Résultat 1.*1. AireRectangle ( ); // Résultat 1.*1. // Appel de la fonction avec un argument par défaut. AireRectangle (5.); // Résultat 5.*1. AireRectangle (5.); // Résultat 5.*1. // Appel de la fonction avec ses arguments donnés. AireRectangle (2.,3.); // Résultat 2.*3. AireRectangle (2.,3.); // Résultat 2.*3.}

12 Spécificité du langage Valeurs des arguments d’une fonction par défaut. Règle 1: Les arguments par défaut sont donnés de droite à gauche: Règle 1: Les arguments par défaut sont donnés de droite à gauche: void Fonction ( int, float =2.,int=1) ; // OK correct void Fonction ( int, float =2.,int=1) ; // OK correct void Fonction ( int =1, float = 2., int ) ; // Erreur Compilation void Fonction ( int =1, float = 2., int ) ; // Erreur Compilation Règle 2: La séquence de valeurs par défaut est continue sans interruption. Règle 2: La séquence de valeurs par défaut est continue sans interruption. void Fonction ( int = 1, float,int=2) ; // Erreur Compilation void Fonction ( int = 1, float,int=2) ; // Erreur Compilation

13 Spécificité du langage Surdéfinition des fonctions Deux fonctions peuvent avoir le même nom mais pas la même liste d’arguments: Deux fonctions peuvent avoir le même nom mais pas la même liste d’arguments: Exemple : Exemple : int Maximum ( int i, int j); int Maximum ( int i, int j); float Maximum ( float x, float y ) ; float Maximum ( float x, float y ) ; Une fonction se distingue par sa liste d’arguments. Une fonction se distingue par sa liste d’arguments. On dit que la fonction est surdéfinie. On dit que la fonction est surdéfinie. On peut surdéfinir une fonction autant de fois que l’on veut. On peut surdéfinir une fonction autant de fois que l’on veut.

14 Spécificité du langage Les opérateurs d’allocation et de destruction dynamiques de la mémoire Les opérateurs new et new []réserve de la mémoire Les opérateurs new et new []réserve de la mémoire Exemple int * ip = new int; Exemple int * ip = new int; int * itab = new int[10]; int * itab = new int[10]; Les opérateurs delete et delete[] libèrent cette zone mémoire. Les opérateurs delete et delete[] libèrent cette zone mémoire. Exemple delete ip ; Exemple delete ip ; delete [] itab ; delete [] itab ; Nécessairement new ==> delete et Nécessairement new ==> delete et new[] ==> delete[] new[] ==> delete[]

15 Chapitre 2 Définition d’une classe.

16 Définition d ’une classe Couplage des données et des fonctions ( appelées méthodes ou fonctions membres) La notion de classe en C++ est une extension de la notion de structure du C avec les concepts fondamentaux suivants: Encapsulation des données, statut privé ( Ces données privées ne peuvent être manipulées que par les méthodes de la classe)

17 Définition d ’une classe class Point { private: float x; float Y; public: Initialise ( float, float ) ; void Affiche(); };

18 Définition d ’une classe La classe est définie dans un fichier d ’extension.h ou.hxx exemple: Point.hxx Les fonctions membres seront définies dans un fichier d ’extension.cxx,.C,.cc,.cpp exemple: Point.cxx Les fonctions sont rattachées à la classe par l ’opérateur de portée :: Exemple: void Point::Initialise( float a,float b)

19 Définition d ’une classe ifndef POINT #define POINT class Point { private : private : float x ; float x ; float y ; float y ; public : public : void Initialise ( float = 0, float = 0 ) ; void Initialise ( float = 0, float = 0 ) ; void Affiche (void) ; void Affiche (void) ; } ; #endif

20 Définition d ’une classe #include "Point.hxx" #include #include void Point::Affiche(void ) { cout << "x = " << x << endl ; cout << "x = " << x << endl ; cout << "y = " << y << endl ; cout << "y = " << y << endl ;} void Point::Initialise(float a, float b) { x=a; x=a; y=b; y=b;}

21 Définition d ’une classe #include "Point.hxx" int main () { int code_error = 1 ; int code_error = 1 ; Point P; Point P; P.Initialise(3,4); P.Initialise(3,4); P.Affiche() ; P.Affiche() ; return code_error; return code_error;}

22 Définition d ’une classe Première approche du constructeur: Initialiser les données au moment de l ’instanciation. Le constructeur porte le même nom que la classe et ne possède pas de variable de retour. Au choix du concepteur, les données (ou attributs), les fonctions membres (ou méthodes) peuvent être déclarées sous le statut public ou private. Les méthodes déclarées sous le statut public constitue l ’interface utilisateur de la classe et définissent les niveaux d ’accessibilité des données qui doivent être déclarées sous le statut private.

23 Définition d ’une classe ifndef POINT #define POINT class Point { private : private : float x ; float x ; float y ; float y ; public : public : Point( float = 0, float = 0 ) ; Point( float = 0, float = 0 ) ; void Initialise ( float = 0, float = 0 ) ; void Initialise ( float = 0, float = 0 ) ; void Affiche (void) ; void Affiche (void) ; } ; #endif

24 Définition d ’une classe #include "Point.hxx" #include #include Point::Point(float a, float b):x(a),y(a) Point::Point(float a, float b):x(a),y(a) { } void Point::Affiche(void ) { cout << "x = " << x << endl ; cout << "x = " << x << endl ; cout << "y = " << y << endl ; cout << "y = " << y << endl ;} void Point::Initialise(float a, float b) { x=a; x=a; y=b; y=b;}

25 Définition d ’une classe #include "Point.hxx" int main () { int code_error = 1 ; int code_error = 1 ; Point P(1,2); Point P(1,2); P.Affiche() ; P.Affiche() ; P.Initialise(3,4); P.Initialise(3,4); P.Affiche() ; P.Affiche() ; return code_error; return code_error;}

26 Définition d ’une classe Constructeurs et destructeurs sont indispensables si la classe possède des objets ou tableaux dynamiques. C ’est dans le constructeur que se fera l ’allocation dynamique par les opérateurs new ou new []. C ’est dans le constructeur que se fera l ’allocation dynamique par les opérateurs new ou new []. C ’est dans le destruteur que se fera la libération de la zone mémoire dynamique par les opérateurs delete C ’est dans le destruteur que se fera la libération de la zone mémoire dynamique par les opérateurs delete ou delete []. ou delete [].

27 Définition d ’une classe # ifndef Vecteur_HeaderFile #define Vecteur_HeaderFile class Vecteur { private: private: int N; int N; float * Coord; float * Coord; public: public: Vecteur( int = 0, float * = NULL); Vecteur( int = 0, float * = NULL);~Vecteur(); void Affiche(); void Affiche(); void Initialise(float *=NULL) ; void Initialise(float *=NULL) ; } ; #endif

28 Définition d ’une classe #include "Vecteur.hxx " #include #include Vecteur::Vecteur(int n, float * A) { cout << " Constructeur usuel " << endl; cout << " Constructeur usuel " << endl; if ( n == 0 ) if ( n == 0 ) { Coord = NULL ; Coord = NULL ; N= 0 ; N= 0 ; } else else { Coord = new float[N=n]; Coord = new float[N=n]; Initialise(A); Initialise(A); }}

29 Définition d ’une classe Vecteur::~Vecteur(){ cout << " Destructeur Vecteur" << N << endl; cout << " Destructeur Vecteur" << N << endl; delete [] Coord ; delete [] Coord ;} void Vecteur::Affiche() { int i; int i; cout << "Pointeur Coord << Coord " << endl; cout << "Pointeur Coord << Coord " << endl; cout << " Vecteur de dimension N = " << N << endl; cout << " Vecteur de dimension N = " << N << endl; for ( i = 0 ; i < N ; i++ ) for ( i = 0 ; i < N ; i++ ) cout << Coord[i] << endl; cout << Coord[i] << endl;}

30 Définition d ’une classe void Vecteur::Initialise(float * A) { int i; int i; if ( A == NULL ) if ( A == NULL ) { for ( i = 0 ; i < N; i++ ) for ( i = 0 ; i < N; i++ ) Coord[i]=0. ; Coord[i]=0. ; else else { for ( i = 0 ; i < N; i++ ) for ( i = 0 ; i < N; i++ ) Coord[i]= A[i] ; Coord[i]= A[i] ; }}

31 Définition d ’une classe #include "Vecteur.hxx" int main () { int code_error = 1 ; int code_error = 1 ; float A[]={1.,2.,3.,4.}; float A[]={1.,2.,3.,4.}; Vecteur V1(3); Vecteur V1(3); V1.Affiche() ; V1.Affiche() ; Vecteur V2(4,A); Vecteur V2(4,A); V2.Affiche() ; V2.Affiche() ; Vecteur V3 = V2 ; Vecteur V3 = V2 ; V3.Affiche() ; V3.Affiche() ; Vecteur V4(0) ; Vecteur V4(0) ; V4.Affiche() ; V4.Affiche() ; Vecteur V5 = V4 ; Vecteur V5 = V4 ; V5.Affiche() ; V5.Affiche() ; return code_error; return code_error;}

32 Définition d ’une classe Problématique du constructeur par recopie. void Fonction ( Vecteur ) ; Vecteur V1(5) ; Vecteur V2 = V1; ======> Recopie Fonction(V1); ======> Recopie Les instructions suivantes impliquent le constructeur par recopie, défini par défaut:

33 Définition d ’une classe Vecteur V1 Vecteur V2 Vecteur V1 Vecteur V2 Objet Vecteur Tableau Dynamique Objet Vecteur

34 Définition d ’une classe Vecteur V1 Vecteur V2 Vecteur V1 Vecteur V2 Objet Vecteur Tableau Dynamique Objet Vecteur Tableau Dynamique

35 Définition d ’une classe Solution obligatoire : Redéfinir le constructeur par recopie. Redéfinir le constructeur par recopie. Son prototype: Vecteur ( const Vecteur &) ( à rajouter dans la définition de la classe, sous le statut public) Vecteur::Vecteur(const Vecteur & V) { Coord = new float [N=V.N]; Coord = new float [N=V.N]; Initialise(V.Coord); Initialise(V.Coord);}

36 Définition d ’une classe Vecteur::Vecteur(const Vecteur & V) { cout << " Constructeur par recopie Vecteur " << endl; cout << " Constructeur par recopie Vecteur " << endl; if ( V.N == 0 ) if ( V.N == 0 ) { Coord = NULL ; Coord = NULL ; N= 0 ; N= 0 ; } else else { Coord = new float[N=V.N]; Coord = new float[N=V.N]; Initialise(V.Coord); Initialise(V.Coord); }}

37 Chapitre 3 Surdéfinition des opérateurs.

38 Surdéfinition des opérateurs Tous les opérateurs peuvent être redéfinis sauf. et pour certains des contraintes ) mais les règles de priorité et d ’associativité sont conservées. Par exemple définissons l ’opérateur + pour la classe Complex. Par exemple définissons l ’opérateur + pour la classe Complex. Complex operator + ( const Complex & ) Complex operator + ( const Complex & ) ( prototype dans la définition de la classe Complex) Complex Complex::operator + ( const Complex & Z) { Complex R; Complex R; R.x=x+Z.x; R.x=x+Z.x; R.y=y+Z.y; R.y=y+Z.y; return R; return R;}

39 Standard Template Library PluralitéOpérateursAssociativité Binaire () [] -> Gauche-droite Unaire + - ++ -- ! ~ * & new new [] delete delete [] (cast) Droite-gauche Binaire * / % Gauche-droite Binaire + - Gauche-droite Binaire > >Gauche-droite Binaire >= >=Gauche-droite Binaire == != Gauche-droite

40 Standard Template Library PluralitéOpérateursAssociativité Binaire&Gauche-droite Binaire.Gauche-droite Binaire||Gauche-droite Binaire&&Gauche-droite Binaire|Gauche-droite Binaire = += -= *= /= %= &= ^= |= >= Droite-Gauche Binaire,Gauche-droite

41 Surdéfinition des opérateurs Problématique de l ’opérateur d ’affectation : V2=V1 Problématique de l ’opérateur d ’affectation : V2=V1 Vecteur V1 Vecteur V2 Vecteur V1 Vecteur V2 Objet Vecteur Tableau Dynamique A1 Objet Vecteur Tableau Dynamique A2

42 Surdéfinition des Opérateurs Vecteur V1 = Vecteur V2 Vecteur V1 = Vecteur V2 Objet Vecteur Tableau Dynamique A1 Objet Vecteur Tableau Dynamique A2

43 Surdéfinition des opérateurs Problématique de l ’opérateur d ’affectation : V2=V1 Problématique de l ’opérateur d ’affectation : V2=V1 Vecteur V1 Vecteur V2 Vecteur V1 Vecteur V2 Objet Vecteur Tableau Dynamique A1 Objet Vecteur Tableau Dynamique A1

44 Surdéfinition des opérateurs Solution obligatoire : Redéfinir l ’opérateur d ’affectation. Redéfinir l ’opérateur d ’affectation. Son prototype: Vecteur & operator = ( const Vecteur &) ( à rajouter dans la définition de la classe, sous le statut public) Vecteur & Vecteur::operator = (const Vecteur & V) { if ( this != &V) if ( this != &V) { delete [] Coord ; delete [] Coord ; Coord = new float [N=V.N]; Coord = new float [N=V.N]; Initialise(V.Coord); Initialise(V.Coord); } return *this ; return *this ;}

45 Surdéfinition des opérateurs Une classe contenant des objets ou des tableaux dynamiques doit impérativement contenir: Au moins un constructeur. Au moins un constructeur. Un destructeur. Un destructeur. Un constructeur par recopie. Un constructeur par recopie. Surdéfinition de l ’opérateur d ’affectation. Surdéfinition de l ’opérateur d ’affectation. Cet ensemble constitue la base canonique de la classe, indispensable pour le bon fonctionnement de la gestion de la mémoire.

46 Surdéfinition des opérateurs Vecteur V1 Vecteur V2 Vecteur V1 Vecteur V2 Objet Vecteur Tableau Dynamique Objet Vecteur Afin d’éviter de dupliquer la zone mémoire, ce problème peut être traiter avec un compteur de référence sur cette zone.

47 Surdéfinition des opérateurs Surdéfinition de l ’opérateur []: On aimerait accéder ou modifier les composantes du vecteur V, soient les valeurs de type float: V.Coord[i], avec une écriture plus directe c ’est à dire V[i]. soient les valeurs de type float: V.Coord[i], avec une écriture plus directe c ’est à dire V[i]. Pour cela il faut surdéfinir l ’ opérateur [] Prototype à déclarer dans classe vecteur: float & operator [] ( int ) float & Vecteur::operator [] ( int i) { return Coord[i] ; return Coord[i] ;}

48 Surdéfinition des opérateurs Surdéfinition de l ’opérateur « Cast »: Conversions implicites (mises en place par le compilateur) ou explicites (appel de l ’opérateur cast) Exemple: int i,j; double x=3.14159; i=x; // Conversion implicite j=int ( x) ; //Conversion explicite Les conversions définies par l ’utilisateur: Reprenons les classes Point et Complex et on aimerait pouvoir convertir un complex en un point et réciproquement. Complex z1(1.,2.); Point P1(1.,2.); Point P2=z1; Complex z2=P1;

49 Surdéfinition des opérateurs Première solution avec les contructeurs: On peut définir un constructeur de la classe Point avec un Complex comme argument On peut définir un constructeur de la classe Point avec un Complex comme argument Point(const Complex &) Point(const Complex &) On peut définir un constructeur de la classe Complex avec un Point comme argument On peut définir un constructeur de la classe Complex avec un Point comme argument Complex(const Point &) Complex(const Point &) Deuxième solution surdéfinir l ’opérateur Cast: point ->Complex point ->Complex Prototype operator Complex() Prototype operator Complex() Complex ->Point Complex ->Point Prototype operator Point() Prototype operator Point()

50 Surdéfinition des opérateurs class Point { class Complex { float x ; float x ; float y ; float y ; …. …. Complex() ; Point() ; …. …. }; }; Point::Complex() Complex::Point() { { return Complex (x,y); return Point(x,y); return Complex (x,y); return Point(x,y); } }

51 Surdéfinition des opérateurs Quelques règles essentielles: On ne peut surdéfinir un opérateur que s ’il comporte au moins un argument ( implicite ou non) de type classe. On ne peut surdéfinir un opérateur que s ’il comporte au moins un argument ( implicite ou non) de type classe. Le mot clé explicit devant le constructeur interdit son utilisation dans des conversions implicites. Le mot clé explicit devant le constructeur interdit son utilisation dans des conversions implicites. Les possibilités de conversion en chaîne sont limitées au nombre de 3. Les possibilités de conversion en chaîne sont limitées au nombre de 3. ( standard, C.D.U., standard) ( standard, C.D.U., standard)

52 Membre Objet d’une classe Considerons la classe Cercle suivante: Class Cercle { Point Centre ; float Rayon; public: Cercle ( float, float, float ); Cercle ( const Point & ); Cercle (const Cercle &) ; };

53 Membre Objet d’une classe Cercle::Cercle(float a, float b, float r):Centre(a,b),Rayon® {} Cercle::Cercle(const Point & P, float r):Centre(P),Rayon(r) {} Cercle::Cercle(const Cercle & C):Centre(C),Rayon(C.Rayon) {}

54 Chapitre 4 Les fonctions et classes amies

55 Les fonctions et les classes amies. Introduction: Reprenons la classe Complex avec la surdéfinition de l ’opérateur + comme fonction membre de la classe. On a vu que l ’on peut définir l ’opération suivante: Complex z1(1.,2); float x=3.; Complex z2=z1+ 3. ; // 3 est converti en Complex implicitement. Par contre, on ne peut pas définir l ’opération: Complex z2 = 3 + z1; Pour pallier à ce problème, on va définir l ’opérateur +, comme fonction indépendante et la déclarer fonction amie de la classe Complex.

56 Les fonctions et les classes amies. class Complex { private: private: … public: public: … friend Complex opérator + ( const Complex &, const Complex & ) ; friend Complex opérator + ( const Complex &, const Complex & ) ;}; Complex opérator + ( const Complex & z1,const Complex & z2) { Complex z; Complex z; z.x=z1.x+z2.x; z.x=z1.x+z2.x; z.y=z1.y+z2.y; z.y=z1.y+z2.y; return z; return z;}

57 Les fonctions et les classes amies. Une fonction indépendante peut être déclarée amie d ’une classe. Une fonction indépendante peut être déclarée amie d ’une classe. ( a accès à tous les membres privés de cette classe.) ( a accès à tous les membres privés de cette classe.) Une fonction membre d ’une autre classe A peut être déclarée amie d’une classe B Une fonction membre d ’une autre classe A peut être déclarée amie d’une classe B ( Cette fonction a accès à tous les membres privés de cette classe B.) ( Cette fonction a accès à tous les membres privés de cette classe B.) Une classe A toute entière peut être déclarée amie d’une classe B. Une classe A toute entière peut être déclarée amie d’une classe B. ( Toutes les fonctions membres de cette classe A amie ont accès à tous ( Toutes les fonctions membres de cette classe A amie ont accès à tous les membres privés de cette classe B.) les membres privés de cette classe B.) La notion d ’amitié casse l ’encapsulation des membres privés.

58 Les fonctions et les classses amies. #include #include class Matrice { …Public: Friend Vecteur operator * ( const Matrice &, const Vecteur &); }; Vecteur operator * (const Matrice & M, const Vecteur & V) { int i,j; int i,j; Vecteur R(M.N) ; Vecteur R(M.N) ; for ( i=0;i<M.N;i++) { for ( i=0;i<M.N;i++) { R[i] = 0. R[i] = 0. for ( j=0;j<M.N;j++) { for ( j=0;j<M.N;j++) { R[i] += M.Lines[i][j] * V[j]; R[i] += M.Lines[i][j] * V[j]; } return R; return R; }

59 Les fonctions et les classes amies. Fonction membre d ’une autre classe, déclarée amie d ’une classe. Exemple: On veut définir l ’opérateur * multiplication d ’une matrice par un vecteur, cet opérateur sera déclaré fonction membre de la classe matrice: Vecteur operator * ( const Vecteur &); Dans la classe Vecteur, cet opérateur sera déclaré fonction amie: friend Vecteur Matrice::operator * ( const Vecteur &); Dans la définition de la classe Matrice, il suffira de signaler au compilateur que la classe Vecteur si elle n ’est pas déjà définie, sera définie ultérieurement par la déclaration suivante: class Vecteur; Par contre, dans la définition de la classe Vecteur, il est obligatoire d ’avoir déjà défini la classe Matrice par la déclaration suivante: #include #include

60 Les fonctions et les classes amies. Classe entière déclarée classe amie d ’une autre classe. On a le choix, on peut simplement signaler dans l ’une ou les deux classes que la classe complémentaire sera définie ultérieurement. que la classe complémentaire sera définie ultérieurement. Cette possibilité est à éviter, on doit encapsuler les données au maximum par principe, pour éviter toute possibilité d ’erreur.

61 Chapitre 5 HéritageHéritage

62 Héritage.Héritage. Concept d ’héritage (un outil puissant) : Il autorise à définir une nouvelle classe dite dérivée à partir d ’une classe existante, dite de base. La classe dérivée héritera des possibilités de la classe de base en lui ajoutant de nouvelles. Exemple: Reprenons la classe Point et à partir de cette classe, définissons une nouvelle classe PointColorie qui héritera de la classe Point. La classe de base Point possède comme attributs l ’abscisse et l ’ordonnée d ’un point; la classe ajoute l ’attribut d ’une couleur. class PointColorie : public Point { int Color; public: PointColorie ( float = 0, float = 0, int = 1 ) ; Initialise ( float = 0, float = 0, int = 1 ) ; void Affiche() ; };

63 Héritage.Héritage. #include #include PointColorie::PointColorie( float a, float b,int c):Point(a,b),Color(c){} void PointColorie::Initialise ( float a, float b,int c) { Point::Initialise(a,b); Color = c ; } void PointColorie::Affiche() { Point::Affiche() ; cout << C << endl; } L ’opérateur Point:: est indispensable ici car Point et PointColorie possèdent les méthodes Affiche et Initialise.

64 Héritage.Héritage. Le statut protected La classe dérivée n ’a pas accès aux membres privés de la classe de base. Il existe un troisième statut protected, les membres protégés d ’une classe de base sont accessibles à toute classe dérivée. Une fonction amie d ’une classe dérivée aura accès aux membres protégés de la classe de base. Par contre, l ’amitié ne s ’hérite pas, une fonction déclarée amie dans une classe de base n ’est pas fonction amie d ’une classe dérivée.

65 Héritage.Héritage. Les différents modes de dérivation Dérivation Publique Classe de baseClasse dérivéeExtérieurNouveau Statut Classe de baseClasse dérivéeExtérieurNouveau Statut Membres Privésnon accessiblesnon accessiblesPrivé Membres Privésnon accessiblesnon accessiblesPrivé Membres Protégés accessiblesnon accessiblesProtected Membres Protégés accessiblesnon accessiblesProtected Membres publiques accessiblesaccessiblespublic Membres publiques accessiblesaccessiblespublic Dérivation Privée Classe de baseClasse dérivéeExtérieurNouveau Statut Classe de baseClasse dérivéeExtérieurNouveau Statut Membres Privésnon accessiblesnon accessiblesprivé Membres Privésnon accessiblesnon accessiblesprivé Membres Protégésaccessiblesnon accessiblesprivé Membres Protégésaccessiblesnon accessiblesprivé Membres publiquesaccessiblesnon accessiblesprivé Membres publiquesaccessiblesnon accessiblesprivé Dérivation protégée Classe de baseClasse dérivéeExtérieurNouveau Statut Classe de baseClasse dérivéeExtérieurNouveau Statut Membres Privésnon accessiblesnon accessiblesprivé Membres Privésnon accessiblesnon accessiblesprivé Membres Protégésaccessiblesnon accessiblesprotected Membres Protégésaccessiblesnon accessiblesprotected Membres publiquesaccessiblesnon accessibles protected Membres publiquesaccessiblesnon accessibles protected

66 Héritage.Héritage. Constructeur par recopie et opérateur d ’affectation dans la classe dérivée. On suppose que le constructeur par recopie et l ’opérateur d ’affection ont été définis dans la classe de base. Si on utilise le constructeur par recopie ou l ’opérateur d ’affection par défaut dans la classe dérivée -> Pas de problème. Si on utilise le constructeur par recopie ou l ’opérateur d ’affection par défaut dans la classe dérivée -> Pas de problème. Si le constructeur par recopie ou l ’opérateur d ’affection ont été redéfinis dans la classe dérivée -> Attention il faudra appeler explicitement le constructeur par recopie ou l ’opérateur d ’affection de la classe de base. Si le constructeur par recopie ou l ’opérateur d ’affection ont été redéfinis dans la classe dérivée -> Attention il faudra appeler explicitement le constructeur par recopie ou l ’opérateur d ’affection de la classe de base.

67 Héritage.Héritage. PointColorie::PointColorie(const PointColorie & P):Point(P) { Couleur=P.Couleur; Couleur=P.Couleur; } PointColorie & PointColorie::operator = (const PointColorie & P) { if ( this != &P) if ( this != &P) { Point::operator = (P) ; Point::operator = (P) ; Couleur = P.Couleur ; Couleur = P.Couleur ;} return *this return *this}

68 Héritage.Héritage. Héritage Multiple Une classe peut hériter de plusieurs classes. Exemple: On s ’est défini la classe Point et la classe Couleur et on veut définir la classe PointColorie qui hérite de Point et de Couleur. class PointColorie: public Point, public Couleur { public: PointColorie( float a, float b, int coul):Point(a,b),Couleur(coul){} void Affiche(){Point::Affiche();Couleur::Affiche();} }; Attention l ’heritage multiple présente des inconvénients!

69 Héritage.Héritage. Héritage Multiple Exemple compliqué: Point PointColorieCercle CercleColorie

70 Héritage.Héritage. Héritage Multiple Exemple compliqué: Point PointColorieCercle CercleColorie Couleur

71 Héritage.Héritage. Conversion entre classe de base et classe dérivée. La conversion implicite ( Cast )classe dérivée en classe de base ne pose aucun problème. Exemple: Point = PointColorie Exemple: Point = PointColorie La conversion inverse ( downcast ) n ’est pas immédiate, on peut surdéfinir un constructeur de la classe dérivée à partir de le classe de base en donnant une valeur par défaut, aux attributs complémentaires. Exemple : PointColorie (const Point &, int = 1) Exemple : PointColorie (const Point &, int = 1) PointColorie = Point Problématique des conversions de pointeurs: Point * = PointColorie * PointColorie * = ( PointColorie *) Point * Utilisation du mot cle: virtual

72 Chapitre 6 PolymorphismePolymorphisme

73 Polymorphisme.Polymorphisme. Classe abstraite : classe Root #ifndef SHAPE #define SHAPE class Shape{ public: virtual float Perimetre () const { return 0. ; } virtual float Aire () const { return 0. ; } virtual float Volume () const { return 0. ; } virtual void PrintName() const = 0 ; virtual void Print() const = 0 ; };#endif

74 Polymorphisme.Polymorphisme. #include #include main(){ Point P(1.2.); Point P(1.2.); Cercle C(3.,4.,1.,); Cercle C(3.,4.,1.,); Cylindre Cyl(5.,6.,2.,3.); Cylindre Cyl(5.,6.,2.,3.); Shape ** ItemTab; Shape ** ItemTab; ItemTab = new Shape * [3]; ItemTab = new Shape * [3]; Shape * AnyItem; Shape * AnyItem; ItemTab[0] = &P; ItemTab[0] = &P; ItemTab[1] = &C; ItemTab[1] = &C; ItemTab[2] = &Cyl; ItemTab[2] = &Cyl;

75 Polymorphisme.Polymorphisme. For ( int i = 0 ; i < 3 : i++ ) { AnyItem = ItemTab[i] ; AnyItem = ItemTab[i] ; AnyItem->Print() ; AnyItem->Print() ; AnyItem->PrintName() ; AnyItem->PrintName() ; cout Perimetre(); cout Perimetre(); cout Aire(); cout Aire(); cout Volume(); cout Volume(); } delete [] ItemTab ; delete [] ItemTab ;}

76 Chapitre 7 Patrons de fonctions et de classes

77 Patrons de Fonctions et de Classes. Patrons de fonctions: #include #include template T maximum (T x, T y) { return x T maximum (T x, T y) { return x<y?y:x;} main () { int i = 1 ; int i = 1 ; int j = 2 ; int j = 2 ; float x = 3.; float x = 3.; float y = 4.; float y = 4.; cout << maximum(i,j) << endl; cout << maximum(i,j) << endl; cout << maximum(x,y) <<endl; cout << maximum(x,y) <<endl;} Forme générale template T myFonction( T x, U y,V z) { …}

78 Patrons de Fonctions et de Classes. Patrons de classes: #ifndef POINT #define POINT template class Point { private: T x ; T y; public: Point ( T = 0, T = 0 ) ; void Affiche () ; };#endif

79 Patrons de Fonctions et de Classes. #include #include template Point ::Point( T a, T b):x(a),y(b){} template void Point ::Affiche() { cout << x << endl ; cout << y << endl; } #include #include main(){ Point P(1,2); Point P(1,2); Point XP(3.,4.); Point XP(3.,4.); P.Affiche(); P.Affiche(); XP.Affiche(); XP.Affiche();}

80 Chapitre 8 Standard Template Library

81 Standard template Library Cette librairie fournit des patrons de fonctions et de classes permettant de définir des collections (conteneurs) d ’objets et des utilitaires (itérateurs et algorithmes) pour manipuler ces collections d ’objets. définir des collections (conteneurs) d ’objets et des utilitaires (itérateurs et algorithmes) pour manipuler ces collections d ’objets. Les conteneurs séquentiels: vector: tableau défini sur un seul bloc. (accès direct) vector: tableau défini sur un seul bloc. (accès direct) deque: tableau défini sur plusieurs blocs. (accès direct) deque: tableau défini sur plusieurs blocs. (accès direct) list: liste doublement chaînée. list: liste doublement chaînée. Les conteneurs associatifs: map clé associée à une valeur.( cas particulier: set) map clé associée à une valeur.( cas particulier: set) multimap clé associée à plusieurs valeurs. ( cas particulier: multiset) multimap clé associée à plusieurs valeurs. ( cas particulier: multiset)

82 Standard Template Library A chaque conteneur, on associe un itérateur, par exemple: vector v(10); vector ::iterator iv; int i=0; for (iv=v.begin();iv!=v.end();iv++) (*iv)=++i; float x[]={1.,2.,3.,4.}; list l(x,x+4); list ::iterator il; for (il=l.begin();il!=l.end();il++) cout << (*il) << endl; Les conteneurs vector et deque sont d ’accès direct, l ’opérateur [] est surdéfini, donc on peut écrire directement: vector v(10); for (int i = 0 ; i < 10 ; i++) v[i] = i ;

83 Standard Template Library Notion d ’algorithmes: A tous ces conteneurs sont associés des patrons de fonctions qui effectuent des opérations. Par exemple la fonction sort (algorithme de tri) int t[]= {5,2,1,3,4}; list l(t,t+5); l.sort(); résultat:1,2,3,4,5 Certains algorithmes sont applicables, d ’autres non, par exemple, l ’algorithme de tri est applicable si une relation d ’ordre a été définie sur les éléments du conteneur list.

84 Standard Template Library Générateurs d ’opérateurs. La bibliothèque peut générer: l ’opérateur != à partir de l ’opérateur == l ’opérateur != à partir de l ’opérateur == les opérateurs >, >=,, >=, <= à partir de l ’opérateur <; Par conséquent, dans une classe, il suffit de la munir des deux seuls opérateurs == et <. Constructeurs et affectation. Tous les conteneurs possèdent un constructeur par recopie et un opérateur d ’affectation. list l(5) ; int t[5]={1,2,3,4,5}; list l(t,t+5); vector v(l.begin(),l.end()); vector v(l.rbegin(),l.rend());

85 Standard Template Library Fonctionnalités communes aux conteneurs séquentiels (vector,deque,list) assign() assign() vector v(…); vector v(…); list l.assign(v.begin(),v.end()); clear() vide le conteneur clear() vide le conteneur swap() échange le contenu de 2 conteneurs de même type. swap() échange le contenu de 2 conteneurs de même type. insert(position,valeur),insert(position,NbFois,valeur),insert(debut,fin,valeur). insert(position,valeur),insert(position,NbFois,valeur),insert(debut,fin,valeur). erase(position),erase(debut,fin) erase(position),erase(debut,fin) push_back() et pop_back() insertion et suppression sur le dernier élément. push_back() et pop_back() insertion et suppression sur le dernier élément. push_front() et pop_front() uniquement pour les conteneurs deque et list. push_front() et pop_front() uniquement pour les conteneurs deque et list.

86 Standard Template Library Fonctionnalités propre au conteneur list. remove(valeur) supprime les éléments égaux à valeur. remove(valeur) supprime les éléments égaux à valeur. remove_if(predicat) remove_if(predicat) sort() et sort(predicat) sort() et sort(predicat) unique() supprime les doublons. unique() supprime les doublons. merge(liste) et merge(liste,predicat) merge(liste) et merge(liste,predicat) splice(position,liste) splice(position,liste)

87 Standard Template Library Les adaptateurs de conteneur:queue,stack,priority_queue stack destiné à la gestion de piles de type (last in, first out) stack destiné à la gestion de piles de type (last in, first out) stack > s1; stack > s1; stack > s2; stack > s2; stack > s3; stack > s3; Interface: empty(),size(),top(),push(valeur),pop() Interface: empty(),size(),top(),push(valeur),pop() queue destiné à la gestion des piles de type (first in, first out) queue destiné à la gestion des piles de type (first in, first out) queue q1; queue q1; queue q2; queue q2; Interface: empty(),size(),front(),back(),push(valeur),pop() Interface: empty(),size(),front(),back(),push(valeur),pop() priority_queue introduction d ’un élément en fin suivant un prédicat. priority_queue introduction d ’un élément en fin suivant un prédicat. priority_queue, greater >q1; priority_queue, greater >q1; Interface: empty(),size(),top(),push(valeur),pop()

88 Standard Template Library #include #include « include « include using namespace std; int main() { int t1[]={3,5,4,7,1,9,2,8,6}; int t1[]={3,5,4,7,1,9,2,8,6}; vector v(t1,t1+6); vector v(t1,t1+6); for (int i =0 ; i<v.size(); i++) cout << v[i] ; for (int i =0 ; i<v.size(); i++) cout << v[i] ; cout << endl; cout << endl; list l1(t1,t1+9); list l1(t1,t1+9); l1.sort(); l1.sort(); list ::iterator il1; list ::iterator il1; for ( il1=l1.begin();il1!=l1.end();il1++) cout << (*il1) ; for ( il1=l1.begin();il1!=l1.end();il1++) cout << (*il1) ; cout << endl; cout << endl;

89 Standard Template Library int t2[]={10,11,12}; int t2[]={10,11,12}; list l2(t2,t2+3); list l2(t2,t2+3); l1.merge(l2); l1.merge(l2); l1.push_back(13); l1.push_back(13); l1.push_front(0); l1.push_front(0); for (il1=l1.begin();il1!=l1.end();il1++) cout << (*il) ; for (il1=l1.begin();il1!=l1.end();il1++) cout << (*il) ; cout << endl; cout << endl;}

90 Standard Template Library Les conteneurs associatifs Le conteneur map Le conteneur map associe une clé et une valeur: associe une clé et une valeur: map m; map m; m[‘a‘] = 1; // associe la valeur 1 à la clé a m[‘a‘] = 1; // associe la valeur 1 à la clé a m[‘b‘] = 2; // associe la valeur 2 à la clé b m[‘b‘] = 2; // associe la valeur 2 à la clé b Le conteneur multimap Le conteneur multimap associe à une clé plusieurs valeurs. associe à une clé plusieurs valeurs. multimap mm; multimap mm; mm.insert(make_pair(‘a‘,1)); mm.insert(make_pair(‘a‘,1)); mm.insert(make_pair(‘a‘,2)); mm.insert(make_pair(‘a‘,2)); Les conteneurs set et multiset sont des conteneurs particuliers de map et multimap.

91 Standard Template Library #include #include using namespace std; main(){ map m; map m; m[‘ a ‘] = 3.; m[‘ a ‘] = 3.; m[‘ b ‘] = 2.; m[‘ b ‘] = 2.; m[‘ a ‘] = 1.; m[‘ a ‘] = 1.; map ::iterator im; map ::iterator im; for ( im=m.begin();im!=m.end();im++) for ( im=m.begin();im!=m.end();im++) { cout << (*im).first << (*im).second << endl ; cout << (*im).first << (*im).second << endl ; }

92 Standard Template Library multimap mm ; mm.insert(make_pair(‘a‘,1)); mm.insert(make_pair(‘a‘,1)); mm.insert(make_pair(‘b‘,10)); mm.insert(make_pair(‘b‘,10)); mm.insert(make_pair(‘c‘,100)); mm.insert(make_pair(‘c‘,100)); multimap mm ::iterator imm; multimap mm ::iterator imm; for (imm=mm.begin();imm!=mm.end();imm++) { for (imm=mm.begin();imm!=mm.end();imm++) { cout << (*imm).first << (*imm).second << endl; } cout << (*imm).first << (*imm).second << endl; } mm.insert(make_pair(‘a‘,2)); mm.insert(make_pair(‘a‘,2)); mm.insert(make_pair(‘b‘,20)); mm.insert(make_pair(‘c‘,200)); for (imm=mm.begin();imm!=mm.end();imm++) { cout << (*imm).first << (*imm).second << endl; } cout << (*imm).first << (*imm).second << endl; } } // fin de main


Télécharger ppt "HistoriqueHistorique 1985 1985 Langage C++, parution du livre Bjarne Stroustrup 1998 Normalisation ANSI."

Présentations similaires


Annonces Google