méthodologie orientée objet - université de mons
TRANSCRIPT
1
P.A._IG Ch - 1M. BENJELLOUN : 2020-21
Mohammed BENJELLOUN
Service d’Informatique
Faculté Polytechnique de Mons
2020-21
Méthodologie Orientée Objet
et Programmation Objet
Développement logiciel
P.A._IG Ch - 2M. BENJELLOUN : 2020-21
La maîtrise du langage de programmation objet C++
L’objectif de cet enseignement
Organisation
1. Le cours magistral comprend
Des notions fondamentales et les possibilités de la programmation orientée objet (programmation en C++ )
2. Les séances de travaux pratiques permettent de mettre en œuvre des programmes en C++.
2
P.A._IG Ch - 3M. BENJELLOUN : 2020-21
Le langage C++ Initiez-vous à la programmation en C++Jesse Liberty, Bradley Jones2012
…Claude DelannoyEyrollesoctobre 2017
Acquérir une parfaite maîtrise du C++ et de la programmation objet
C++ et Programmation Objet
P.A._IG Ch - 4M. BENJELLOUN : 2020-21
Structure comportant des fonctions membres
Classe et Objet
Encapsulation
Manipulation des membres privés
Initialisation et affectation
Le pointeur courant this
Constructeur et destructeur
Tableaux d’objets
Règles de visibilité des objets !!!
Surcharge des opérateurs
Patrons : Fonctions et classes
Amies : fonctions et classes
Héritage
STL
C++ et Programmation Objet
3
P.A._IG Ch - 5M. BENJELLOUN : 2020-21
struct point{ int x ;int y ;
} ;
• initialise pour attribuer des valeurs aux "coordonnées" d'un point ;• affiche pour afficher un point .
Supposons que nous souhaitions associer à la structure 2 fonctions :
struct point {int x ; int y ;
void initialise (int, int) ;void affiche () ;
} ;
X1Y1initialise();affiche();
X2Y2initialise();affiche();
X3Y3initialise();affiche();
…
Données
Méthodes
Structure comportant des fonctions membres
structure + fonctions
Fonctions membres :
P.A._IG Ch - 6M. BENJELLOUN : 2020-21
#include <iostream>
using namespace std ;
struct point {
int x, y ;
void initialise (int, int) ;
void affiche () ;
} ;
void point::initialise (int abs, int ord) {
x = abs ;
y = ord ;
}
void point::affiche () {
cout << "Je suis en " << x << " " << y << endl ;
}
void Affiche2(point A, point B){ // fonction non membre
cout << "\n ....Je suis dans Affiche2 ...."<<"\n" ;
A.affiche();
B.affiche();
}
Définition et déclaration des fonctions membres
point::initialise
opérateur de "résolution de portée"
structure + fonctions
4
P.A._IG Ch - 7M. BENJELLOUN : 2020-21 structure + fonctions
Je suis en 5 2Je suis en 1 -1
....Je suis dans Affiche2 ....Je suis en 5 2Je suis en 10 30
Définition et déclaration des fonctions membres
#include <iostream>
using namespace std ;
struct point {
int x, y ;
void initialise (int, int) ;
void affiche () ;
} ;
void point::initialise (int abs, int ord) {
x = abs ;
y = ord ;
}
void point::affiche () {
cout << "Je suis en " << x << " " << y << endl ;
}
void Affiche2(point A, point B){ // fonction non membre
cout << "\n ....Je suis dans Affiche2 ...."<<"\n" ;
A.affiche();
B.affiche();
}
void main() {
point a, b, c ;
// on peut accéder aux "membre " avec .
a.initialise (5, 2) ; a.affiche () ;
b.initialise (1,-1) ; b.affiche () ;
c.x = 10; c.y=30;
Affiche2(a, c);
}
Exécution
P.A._IG Ch - 8M. BENJELLOUN : 2020-21
struct point {
int x, y ;
void initialise (int, int) ;
void affiche ( ) ;
} ;
void point::initialise (int abs, int ord) {
x = abs ; y = ord ;
}
struct point {
int x, y ;
void initialise (int abs, int ord) {
x = abs ; y = ord ;
}
void affiche () ;
} ;
meilleure lisibilité du programme!!!
Définition et déclaration des fonctions membres
5
P.A._IG Ch - 9M. BENJELLOUN : 2020-21
nom1Id1saisie();affiche();
nom2Id2saisie();affiche();
nom3Id3saisie();affiche();
nom4Id4saisie();affiche();
…
T[0] T[1] T[2]struct Etudiant {
int Id;string nom;void saisie();void affiche();
};
void Affichage(Etudiant T[],int n){
for( int i =0; i<n;i++)
T[i].affiche();
}
void Etudiant::affiche() {
cout<<"\t ID:"<< Id <<"\t Nom:"<< nom <<endl;
}
structure + fonctions
Tableau de structures
P.A._IG Ch - 10M. BENJELLOUN : 2020-21
Modélisation de la Gestion des Étudiants FPMs
Structure oui, mais!!
Classe & Objet
Cahier des charges
L’UMONS veut ré-informatiser son système d'information qui gère les étudiants.
Sachant que :
· Un étudiant est caractérisé par [no. matricule, nom, prénom, date de naissance, adresse, Email, moyenne, … ].
· Une classe est caractérisée par son nom et par une indication du groupe ou spécialité ainsi que par le nombre d’étudiants qui la fréquente.
On désire également saisir tous les enseignants dans le système d'information. Un enseignant est caractérisé par un code interne (CodeEnsieg), nom, prénom, statut, Email, salaire et la/les matière(s) qu'il enseigne.
Une matière (cours) peut être composée de cours, T.P. et Exercices.
…
6
P.A._IG Ch - 11M. BENJELLOUN : 2020-21
Etudiant
N° Matricule
Nom
Prénom
Date_Nais
Adresse
Moyenne
…
Enseigner
Année
Enseignant
Code.Enseig
Nom
Prénom
Statut
Salaire
…
Matière
Code.Mat
Intitulé
ECTS
…
Classe & Objet
Modélisation de la Gestion des Étudiants FPMs
Structure oui, mais!!
P.A._IG Ch - 12M. BENJELLOUN : 2020-21
struct Patient {// Données membres
string Nom, Prenom; string maladies;
// Fonctions membres
void Saisir ();void Afficher ();
};
struct Medecin {// Données membres
string Nom, Prenom; string INAMI;
// Fonctions membres
void Saisir ();void Afficher ();
};
struct Client {// Données membres
string Nom; string Adresse;
// Fonctions membres
void Saisir ();void Afficher ();
};
Structure oui, mais!!
struct Banque {// Données membres
string Nom;
…
};
7
P.A._IG Ch - 13M. BENJELLOUN : 2020-21
La déclaration d'une classe est similaire à 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 et/ou données) et les membres
privés en utilisant les mots clés public et private.
Définition d'une classe
struct Patient {// Données membres
string Nom, Prenom; string maladies;
// Fonctions membres
void Saisir ();void Afficher ();
};Accessibles depuisl'extérieur de la classe
class Patient {private:// Données membres
string Nom, Prenom; string maladies;public :// Fonctions membres
void Saisir ();void Afficher ();
};
Cachées auxfonctions externes
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 .
Classe et Objet
P.A._IG Ch - 14M. BENJELLOUN : 2020-21
Encapsulation :
Tous les attributs d'une classe doivent "toujours" être privéspour ne pas être modifier depuis l'extérieur de la classe.
On ne peut accéder à un objet que grâce à ses méthodes publiques.L'ensemble des méthodes publiques est appelé l'interface de l'objet.
Données privées → accès uniquement par les fonctions membres (public)
Classe & Objet
Classe et Objet
masquage des données
Accessibles depuisl'extérieur de la classe
class Patient {private:// Données membres
string Nom, Prenom; string maladies;public :// Fonctions membres
void Saisir ();void Afficher ();
};
Cachées auxfonctions externes
8
P.A._IG Ch - 15M. BENJELLOUN : 2020-21
Un membre déclaré public dans une classe peut être accédé par toutes les autres classes et fonctions.
Le mot-clé private est employé pour signaler quelle partie de la classe restera inaccessible à un utilisateur externe de la classe. Un membre déclaré private dans une classe ne peut être accédé que par les autres membres de cette même classe.
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.
Que signifient les mots clés public, private et protected ?
Ces mots clés peuvent apparaître à plusieurs reprises dans la définition d'une classe :
class X { private :
...public :
...private :
...} ;
Classe & Objet
P.A._IG Ch - 16M. BENJELLOUN : 2020-21
void point::initialise (int abs, int ord) {
x = abs ; y = ord ;
}
void point::affiche () {
cout << "Je suis en " << x << " " << y << "\n" ;
}
void main() {
point a, c ;
a.initialise (5, 2) ; a.affiche () ; a.z = 9;
cout << " Valeur de z = " << a.z << endl;
c.z = 15;
cout << " Valeur de z = " << c.z << endl;
c.x = 10; c.y=30;
c.affiche ();
}
class point {
private: int x, y;
public :
int z;
void initialise (int, int) ;
void affiche () ;
} ;
struct point {
int x, y;
int z;
void initialise (int, int) ;
void affiche () ;
} ;
error C2248: 'point::x' : impossible d'accéder à private
membre déclaré(e) dans la classe 'point'
Classe & Objet
Je suis en 5 2Valeur de z = 9Valeur de z = 15Je suis en 10 30
Exécution
Exemple
9
P.A._IG Ch - 17M. BENJELLOUN : 2020-21
#include <iostream>
using namespace std;
#include <cmath>
class Point {
public:
float x,y;
float distance( Point P);
Point milieu( Point P);
};
float Point::distance( Point P) {
float dx,dy;
dx = x - P.x;
dy = y - P.y;
return sqrt(dx*dx + dy*dy);
}
Point Point::milieu( Point P) {
Point M;
M.x = (P.x+x) /2;
M.y = (P.y+y) /2;
return M;
}
void main() {
Point A, B, C;
float d;
A.x = 4 ; A.y = 3 ;
B.x = 5 ; B.y = 8 ;
C = A.milieu(B);
d = A.distance(B);
cout << endl;
cout << "MILIEU DE AB" << endl;
cout << "L'abscisse vaut : " << C.x << endl;
cout << "L'ordonnée vaut : " << C.y << endl;
cout << "La distance AB vaut :" << d << endl;
}
Exécution
Classe & Objet
MILIEU DE ABL'abscisse vaut : 4.5L'ordonnée vaut : 5.5La distance AB vaut : 5.09902
Exemple
P.A._IG Ch - 18M. BENJELLOUN : 2020-21
class point {
private : // déclaration des membres privés
int x ;
int y ;
public : // déclaration des membres publics
void initialise (int, int) ;
void affiche () ;
} ;
class point {
int x ;
int y ;
public :
void initialise (int, int) ;
void affiche () ;
} ;
struct point { class point {
int x, y ; public :
int x , y;
void initialise (...) ; void initialise (...) ;
..... .....
} ; } ;
Les attributs et méthodes d'une structure sont par défaut publics
Classe & Objet
10
P.A._IG Ch - 19M. BENJELLOUN : 2020-21
Programmation orientée objet !!
TRI
MinMax
Inverser
Fusionner
…
Code
Les attributs = les variables dans le code
Moyenne
Le contenu de l'objet = "boîte noire". On ne sait pas comment ça fonctionne à l'intérieur quand on l'utilise. C'est une sécurité.
Le but du modèle objet est de masquer les informations complexes à l'utilisateur (les attributs) pour éviter qu'il ne fasse des «bêtises» avec.
Exemple : conducteur peut démarrer le moteur mais pas l’ouvrir et …
Interface
TRI
Min
Max
Inverser
Fusionner
Les boutons sur la façade avant, ce sont les méthodes.
Classe & Objet
on n’y peut accéder que par les méthodes publiques.
P.A._IG Ch - 20M. BENJELLOUN : 2020-21
Un objet est une instanciation d’une classe.
Cet objet possède tous les attributs et toutes les fonctions membres de la classe, mais avec des valeurs d’attributs propres à l’objet.
class Etudiant {
private : string Nom ;
int NoteMath;
int NoteInfo;
public:
void Saisie();
float Moyenne();
};
Classe Etudiant
Attributs :
Nom
NoteInfo
NoteMath
Méthodes:
Saisie
Moyenne
Classe Etudiant
Attributs :
Nom
NoteInfo
NoteMath
Méthodes:
Saisie
Moyenne
Obélix
15
11
Obélix
15
11
Astérix
5
18
Astérix
5
18
instance instance Notations UML
possibles d'une classe
Etudiant
Nom : string
NoteInfo : entier
NoteMath : entier
Saisie() : void
Moyenne(): réel
Deux objets étudiants
Un objet !!
Classe & Objet
11
P.A._IG Ch - 21M. BENJELLOUN : 2020-21
#include <iostream>
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();
}
#include <iostream>
using namespace std;
class CRec {
int Long, Larg;
public:
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();
}
Classe & Objet
Initialisation et affectation Données membres : public et private
P.A._IG Ch - 22M. BENJELLOUN : 2020-21
#include <iostream>
using namespace std;
class CRec {
int Long, Larg;
public:
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();
}
#include <iostream>
using namespace std;
class CRec {
int Long, Larg;
public:
int CalcSurf() { return (Long*Larg); }void initialise(int Lo, int La) {
Long = Lo; Larg = La;
}
};
void main() {
CRec Rc1, Rc2;
int Surface = 0;
Rc1.initialise( 30, 24);
Rc2.initialise( Rc1.Long/2, Rc1.Larg*2);
Surface = Rc1.CalcSurf();
cout << endl
<< "Surface rectangle 1 = " << Surface;
cout << endl << " Surface rectangle 2 = "
<< Rc2.CalcSurf();
}
cannot access private member
declared in class 'CRec'
Classe & Objet
Initialisation et affectation Données membres : public et private
12
P.A._IG Ch - 23M. BENJELLOUN : 2020-21 Classe & Objet
#include <iostream>
using namespace std;
class CRec {
int Long, Larg;
public:
int CalcSurf() { return (Long*Larg); }void initialise(int Lo, int La) {
Long = Lo; Larg = La;
}
};
void main() {
CRec Rc1, Rc2;
int Surface = 0;
Rc1.initialise( 30, 24);
Rc2.initialise( Rc1.Long/2, Rc1.Larg*2);
Surface = Rc1.CalcSurf();
cout << endl
<< "Surface rectangle 1 = " << Surface;
cout << endl
<< " Surface rectangle 2 = "
<< Rc2.CalcSurf();
}
#include <iostream>
using namespace std;
class CRec {
int Long, Larg;
public:
int CalcSurf() { return (Long*Larg); }void initialise(int Lo, int La) {
Long = Lo; Larg = La;
}
int R_Long(){ return Long; }
int R_Larg(){ return Larg; }
};
void main() {
CRec Rc1, Rc2;
int Surface = 0; Rc1.initialise( 30, 24);
Rc2.initialise( Rc1. R_Long()/2, Rc1.R_Larg()*2);
Surface = Rc1.CalcSurf();
cout << endl
<< "Surface rectangle 1 = " << Surface;
cout << endl
<< " Surface rectangle 2 = "
<< Rc2.CalcSurf();
}
Initialisation et affectation Données membres : public et private
P.A._IG Ch - 24M. BENJELLOUN : 2020-21
#include <iostream>
using namespace std;
class point {
int x, y;
public :
void initialise (int abs, int ord){
x = abs ; y = ord ;
}
…
} ;
void main(){
point Obj;
int Som;
…
}
void initialise (int x, int y){
x = x ; y = y ;
this->x = x ; this->y = y ;
(*this).x = x ; (*this).y = y ;
}
Accéder aux attributs en cas d’ambiguïté
Les trois lignes sont équivalentes
Classe & Objet
Le pointeur courant this
13
P.A._IG Ch - 25M. BENJELLOUN : 2020-21
Le mot clé this permet de désigner l'objet dans lequel on se trouve. this est passée en tant que paramètre caché de chaque fonction membre.
Il permet d’accéder à une donnée membre d'un objet à partir d'une fonction membre du même objet.
void initialise (int x, int y){this->x = x ; this-> y = y ;
}
this est implicite si l'on donne des noms différents aux données membres et aux variables utilisées dans les fonctions membres.
void initialise (int abs, int ord){x = abs ; y = ord ;
}
Implicitementthis->x
this
Le pointeur courant this
P.A._IG Ch - 26M. BENJELLOUN : 2020-21
dans le cas où l'on désire qu’une fonction membre retourne un pointeur vers l'objet dans lequel elle se trouve.
class Toto{
private :
int age;
public :
void DefineTotoAge(int);
Toto * RetourneToto();
};
void Toto::DefineTotoAge(int age) {
this->age = age;
}
Toto * Toto::RetourneToto(){
return this;
}
Chaque objet (ici de type Personnage) possède un pointeur this qui pointe vers... l'objet lui-même !
Personnage* Personnage::getAdresse() { return this;}
this étant un pointeur sur un objet, *this est l'objet lui-même
this est un pointeur constant, on ne peut donc pas le modifier.
this est indispensable
this
Le pointeur courant this
14
P.A._IG Ch - 27M. BENJELLOUN : 2020-21
Appels en cascade de this
Équivalent àobjet.incrementer();objet.incrementer();objet.incrementer();
#include <iostream>
using namespace std;
class K {
private: int Val;
public:
K() { Val = 0; }
int RetourVal() {
return Val;
}
K& incrementer();
};
K& K::incrementer() {
Val++;
cout << " Val= " << Val;
return *this;
}
void main( ) {
K objet;
cout << " Val = " << ojet.incrementer().incrementer().incrementer().RetourVal() << endl;
objet.incrementer();
}
Solution :Val= 1 Val= 2 Val= 3 Val = 3Val= 4
this
P.A._IG Ch - 28M. BENJELLOUN : 2020-21
#include<iostream>
using namespace std;
class KLa {
private: int x;
public :
KLa & set (int i) { x=i; return *this ; }
KLa & add (int i) { x+=i; return *this ; }
KLa & sub (int i) { x-=i; return *this ; }
int get_x () { return x; }
};
int main() {
KLa A;
cout<< A.set(10).add(15).sub(3).get_x() << endl;
return 1;
}
Solution : 10+15-3 : 22
Le pointeur this permet d’obtenir une référence sur l’instance, plutôt qu’un pointeur. Cela permet d’enchaîner plusieurs appels de méthodes.
this
15
P.A._IG Ch - 29M. BENJELLOUN : 2020-21
Le constructeur :* porte le nom de sa classe,* définit l'initialisation d'une instance, * est appelé implicitement à toute création d'instance, * n'a pas de type de retour (même pas void), * peut admettre des arguments qui sont en fait les valeurs d’initialisation des différents champs de la variable.
Le destructeur :* porte le nom de sa classe précédé d'un tilde (~),* définit la "désinitialisation" d'une instance, * est appelé implicitement à toute disparition d'instance, * n'a pas de type de retour (même pas void), * est une fonction membre non typée et sans paramètre.
class point{
int x, y ;
public :
point (int, int) ; // constructeur
point (float, float) ; // constructeur
point () ; // constructeur
~point () ; // 1 destructeur
} ;
Possibilité de plusieurs constructeurs (surcharge de méthodes) mais un seul destructeur par classe !
Un constructeur est une fonction membre d’initialisation exécutée automatiquement à chaque création d'un objet.
Un destructeur est une fonction membre appelée automatiquement au moment de la destruction de l'objet.
Constructeur et destructeur
P.A._IG Ch - 30M. BENJELLOUN : 2020-21
point::point() {
x = 0;
y = 0;
}
Un constructeur par défaut est un constructeur qui n’a pas d’argument ou dont tous les arguments ont des valeurs par défaut.A::A(); // Sans arguments ! A::A(int X=0, int Y=5); // Valeurs par défaut des arguments ! Rôle : il crée une instance non initialisée quand aucun autre constructeur fourni n’est applicable.
class Etudiant {
private : int Id ;
string Nom ;
public:
Etudiant() { // Constructeur
cout << "Dans constructeur"<<endl;
Id = -1 ; Nom = "Vide";
}
};
class point {
int x, y ;
public :
point () ; // constructeur
~ point (); // destructeur
} ;
point :: ~ point () {
x= -1; y = -1;
}
Les données membres sont créées mais ne sont pas initialisées
Constructeur par défaut
Constructeur & destructeur
A::A(); exemple :
16
P.A._IG Ch - 31M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
using namespace std ;
class Etudiant {
private : int Id ; string Nom ;
public:
Etudiant() { // Constructeur
cout << "Dans constructeur"<<endl;
Id = -1 ; Nom = "Vide";
}
~Etudiant() { // Destructeur
cout << "Dans destructeur\n";
}
void Affiche(){
cout << " Identifiant ="<< Id << endl;
cout << " Son nom : "<< Nom << endl;
}
void modif(int p1, string p2);
};
void Etudiant::modif(int p1, string p2){
cout << "Dans Modif"<<endl;
Id = p1; Nom = p2;
}
Dans constructeurIdentifiant =-1Son nom : Vide
Dans ModifIdentifiant =9Son nom : Toto
Dans destructeur
void main(){
Etudiant Etud;
Etud.Affiche();
Etud.modif(9, "Toto");
Etud.Affiche();
}
Constructeur & destructeur
Exemple de constructeurs par défaut sans paramètres
Exécution
P.A._IG Ch - 32M. BENJELLOUN : 2020-21
#include <iostream>
using namespace std ;
class Cpte_obj {
static int ctr ; // compteur du nombre d'objets créés
public :
Cpte_obj () ;
~Cpte_obj() ;
} ;
// initialisation du membre statique ctr
int Cpte_obj::ctr = 0;
Cpte_obj::Cpte_obj () { // constructeur
cout << "++ constr. il y a : " << ++ctr
<< " objet(s)\n" ;
}
Cpte_obj::~Cpte_obj () { // destructeur
cout << "-- destr. il reste " << --ctr
<< " objet(s)\n" ;
}
void fct() {
Cpte_obj u, v ;
}
int main(){
Cpte_obj A;
fct () ;
Cpte_obj B ;
return 1;
}
++ constr. il y a : 1 objet(s)++ constr. il y a : 2 objet(s)++ constr. il y a : 3 objet(s)-- destr. il reste 2 objet(s)-- destr. il reste 1 objet(s)++ constr. il y a : 2 objet(s)-- destr. il reste 1 objet(s)-- destr. il reste 0 objet(s)
L’initialisation d’un
attribut static est faite en dehors de la classe
Constructeur & destructeur
Exemple de constructeurs par défaut sans paramètres
Exécution
On souhaite compter le nombre d’instances d’une classe actives à un moment donné dans un programme.Utilisons comme compteur un attribut static de type entier : ◮ le constructeur incrémente le compteur ctr ◮ le destructeur le décrémente
17
P.A._IG Ch - 33M. BENJELLOUN : 2020-21
class CRec {
int Long, Larg;
public:
void initialise(int Lo, int La){
Long = Lo; Larg = La;
}
};
class CRec {
int Long, Larg;
public:
CRec (int Lo, int La){
Long = Lo; Larg = La;
}
};
CRec Rc1;
Rc1.initialise(30, 24); CRec Rc1(30, 24);
class Etudiant {
private : int Id ; string Nom ;
public:
Etudiant(int p1, string p2) {
Id = p1 ; Nom = p2;
}
};
class Tab{ int dim, *TabD;
public :
Tab ( int dim ) {
TabD = new Tab [dim] ;
}
~ Tab () {
delete [] TabD ;
}
};
Constructeur par paramètres
Constructeur & destructeur
ICI
P.A._IG Ch - 34M. BENJELLOUN : 2020-21
class Arbre {
int contenu;
Arbre filsG, filsD;
public:
Arbre(Arbre g, int c, Arbre d) {
filsG = g;
contenu = c;
filsD = d;
}
} ;
class Pol {
int coeff, degre;
Pol suivant;
public:
Pol(int c, int d, Pol p) {
coeff = c;
degre = d;
suivant = p;
}
};
Constructeur & destructeur
Exemples de constructeurs par paramètres
Polynômes
class CRec {
int Long, Larg;
public:
CRec (int Lo, int La){
Long = Lo;
Larg = La;
}
};
18
P.A._IG Ch - 35M. BENJELLOUN : 2020-21
Initialisation, affectation d’un objet
par un autre de la même classe.
#include <iostream>
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 SP“<< endl ; }
int CalcSurf() { return (Long*Larg); }
};
void main() {
CRec Rc1(10,20), Rc2;
cout << "\n Surface rectangle 1 = " << Rc1.CalcSurf();
Rc2 = Rc1;
cout << "\n Surface rectangle 2 = " << Rc2.CalcSurf();
}
In Constructeur Param………
Constructeur & destructeur
Exemples de constructeurs par paramètres
Exécution
P.A._IG Ch - 36M. BENJELLOUN : 2020-21
Un constructeur par défaut et par paramètres est un 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; // OKCRec Y(1); // OKCRec Z(1,2); // OK
constructeur (0, 1 ou 2 arguments)
Constructeur par défaut et par paramètres
Constructeur & destructeur
19
P.A._IG Ch - 37M. BENJELLOUN : 2020-21
class Etudiant {
private : int Id= 0 puis 1 puis 2 .. ;
string Nom ;
error C2252: 'Id' : pure specifier can only be specified for functions
???
class Etudiant {
private : int Id ; char code ;
public:
Etudiant() { // Constructeur
cout << "Dans constructeur"<<endl;
static i=1; // compteur du nombre
d'objets créés
static char K='A';
Id = i;
code = K;
i++;
K++;
}
…
void main(){
Etudiant E1; E1.Affiche();
Etudiant E2; E2.Affiche();
Etudiant E3; E3.Affiche();
}
Dans constructeur………
Constructeur & destructeur
Exécution
P.A._IG Ch - 38M. BENJELLOUN : 2020-21
Règles de visibilité des objets !!!
Constructeur & destructeur
20
P.A._IG Ch - 39M. BENJELLOUN : 2020-21
#include <iostream>
using namespace std;
class E {
public : int x, y ;
E () { // constructeur
cout << " +++ Const " << endl;
}
~ E (){ // destructeur
cout << " --- Destr " << endl;
}
};
void Fonct1(){
cout << " ===== Fonct1 " << endl;
E Obj1, Obj2;Obj1.x=10, Obj1.y=20;
}
void main( ) {
cout << " ***** main " << endl;
E V;
Fonct1();
cout << " ***** Fin main " << endl;
}
Variable locale
E Glob;
Variable globale
visibilité des objets
Exemple
P.A._IG Ch - 40M. BENJELLOUN : 2020-21
…
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 d’un objet de classe point
void fct(){
cout << " ====== Debut Fct \n" ;
point b(10,10) , c (3,3) ; // Local dans la fonction
cout << " ====== Fin Fct \n" ;
}
void main() {
cout << "****** Debut main *****\n" ;
fct();
point d(20,20);
for (int 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" ;
}
point a(1,1) est une variable globale construite avant le début de l’exécution de la fonction main.
****** Debut main *****====== Debut Fct
++ Construction d'un point : 10 10++ Construction d'un point : 3 3
====== Fin Fct-- Destruction du point : 3 3-- Destruction du point : 10 10++ Construction d'un point : 20 20--->> Boucle tour numero 1++ Construction d'un point : 1 2-- Destruction du point : 1 2--->> Boucle tour numero 2++ Construction d'un point : 2 4-- Destruction du point : 2 4****** Fin main ******-- Destruction du point : 20 20
++ Construction d'un point : 1 1
-- Destruction du point : 1 1
visibilité des objets
Exemple
Exécution
21
P.A._IG Ch - 41M. BENJELLOUN : 2020-21
…
class E {
public : int x, y ;
E () { // constructeur
cout << " +++ Const " << endl; }
~ E (){ // destructeur
cout << " --- Destr " << endl; }
};
void fonct2 (E &a) {
cout << " ***** Fct 2 " << endl;
E S;
a.x=1 ; a.y=2;
S.x=5; S.y=7;
}
void fonct3 () {
cout << " ***** Fct 3 " << endl;
static E B;
B.x=1; B.y=2;
}
void main( BA){
cout << " ***** main " << endl;
E V;
V.x=V.y=0;
fonct2 (V);
cout << V.x << V.y << endl;
fonct3 ();
fonct3 ();
cout << " ***** Fin main " << endl;
}
Appel par références et variable static ??!!
***** main+++ Const***** Fct 2+++ Const--- Destr1 2***** Fct 3+++ Const***** Fct 3***** Fin main--- Destr--- Destr
// E V;
// E S;
// E S;
// E B;
// E B;
// E V;
Exemple
P.A._IG Ch - 42M. BENJELLOUN : 2020-21
Constructeur de copie
Le constructeur de copie (ou de recopie) est spécialisé dans la création etl’initialisation d’un objet à partir d’un autre objet pris comme modèle. Il estdonc appelé lorsqu’on doit créer une instance d’un objet qui est la copie d’unautre objet.
C’est un constructeur dont le premier paramètre est de type « C & »(référence sur un C) ou « const C &» (référence sur un C constant) et dont lesautres paramètres, s'ils existent, ont des valeurs par défaut.
La syntaxe habituelle d’un constructeur de copie est la suivante :point::point(const point& Pt) // Pt est l'objet à copier point(const point& Pt) // Si définition dans la classe
Constructeur & destructeur
22
P.A._IG Ch - 43M. BENJELLOUN : 2020-21
…
class E {
public : int x, y ;
E () { // constructeur
cout << " +++ Const " << endl;
}
~ E (){ // destructeur
cout << " --- Destr " << endl;
}
E(E &){
cout << "\n ++ const. +++ copie \n";
}
};
E Glob;
void fonct1 (E a) {
cout << " ***** Fct 1 " << endl;
a.x=3 ; a.y=4;
}
void main(B){
cout << " ***** main " << endl;
E V;
V.x=V.y=0;
fonct1 (V);
cout << V.x << V.y << endl;
cout << " ***** Fin main " << endl;
}
+++ Const***** main+++ Const
++ const. +++ copie
***** Fct 1--- Destr0 0***** Fin main--- Destr--- Destr
Constructeur de copie
visibilité des objets
P.A._IG Ch - 44M. BENJELLOUN : 2020-21
Constructeur de copie, objet dynamique
Constructeur & destructeur
#include <iostream>
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
cout << "destruction : " << x << "- " << y << "\n";
}
} ;
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 ;
}
void fct (demo d, demo * add)
{ cout << "entree fct\n" ;
delete add ;
cout << "sortie fct\n" ;
}
void main () {
demo * adr;
cout << "debut main\n" ;
demo a ;
demo b = 2 ;
demo c = a ;
adr = new demo (3,3) ;
fct (a, adr) ;
cout << "fin main\n" ;
}
debut mainconstructeur I : 1 - 0constructeur I : 2 - 0constructeur II (recopie) : 1 - 0constructeur I : 3 - 3constructeur II (recopie) : 1 - 0entree fctdestruction : 3 - 3sortie fctdestruction : 1 - 0fin maindestruction : 1 - 0destruction : 2 - 0destruction : 1 - 0
Exécution
Un constructeur qui sert à créer un objet
identique à l’objet reçu en paramètre.
23
P.A._IG Ch - 45M. BENJELLOUN : 2020-21
La plupart des constructeurs ne font qu’initialiser les données membres de l’objet. Le C++ propose un dispositif appelé liste d’initialisation. L’exemple suivant illustre comment on peut réécrire les constructeurs des différents exemples à l’aide d’une liste d’initialisation.
Listes d’initialisation des constructeurs
Etudiant() {Id = -1 ; Nom = "Vide";
}
Etudiant() : Id (-1) , Nom ("Vide") { }
point (int abs, int ord) {x = abs ; y = ord ; }
point (int abs, int ord) : x (abs) , y (ord) { }
CRec (int Lo = 0, int La = 0) {Long = Lo; Larg = La;
}
CRec (int Lo = 0, int La = 0) : Long (Lo) , Larg (La) { }
Constructeur & destructeur
P.A._IG Ch - 46M. BENJELLOUN : 2020-21
L’utilisation d'un constructeur n'est pas obligatoire lorsqu'il n'est pas nécessaire.
Et surtout pas d’utilisation de constructeur vide.
Constructeur & destructeur
class CRec {
int Long, Larg;
public:
CRec (int Lo, int La) { }
};
24
P.A._IG Ch - 47M. BENJELLOUN : 2020-21
int x, y;if (x == y) { .….}
C++ offre au programmeur la possibilité de définir la plupart des opérateurs pour une classe quelconque.
class point {private : int x, y;
public :
point(int a, int b){
x=a; y =b;
}
operator==(point Pt);
};
void main() {
point a(3,7), b(4, 4);
if (a==b) // a.operateur==
cout << " Oui EGALITE "<< endl;
else
cout << " Non EGALITE "<< endl;
}
int point::operator==(point b) {
if ( (x == b.x) && (y == b.y) ) return 1 ;
else return 0;
}
Toute valeur non nulle est considérée comme vraie et la valeur nulle comme fausse.
if (i) if (i != 0)
Surcharge des opérateurs
La surcharge d’opérateurs permet d’utiliser des écritures plus naturelles, d’étendre l’utilisation des opérateurs usuels à des nouvelles classes.
Et si x et y étaient des objets?
P.A._IG Ch - 48M. BENJELLOUN : 2020-21
int operator ==(PROF A) {
if(Service==A.Service && nom== A.nom) return 1;
else return 0;
};
int recherche(PROF Tab[], int n) ; {
PROF Prof;
Prof.Saisie();
for(int i = 0; i<n ; i++) {
if( Tab[i] == Prof) {
return i;
}
}
…
}
Surcharge des opérateurs
Ecrire Tab[i] == Prof revient à appeler la méthode de classe operator ==// Tab[i].operateur== ; if(Tab[i].Service== A.Service && Tab[i].nom== A. nom) return 1;
Surcharge des opérateurs : exemples
25
P.A._IG Ch - 49M. BENJELLOUN : 2020-21
Ecrire un programme utilisant une classe point permettant de manipuler des points à 2 composantes (x, y) de types int. On y prévoira :
• la définition d’un opérateur + afin d'additionner deux points,• la définition d’un opérateur - afin de soustraire deux points,• la définition d’un opérateur * afin de multiplier deux points.
Utilisez la fonction main() suivante comme programme d'essai de ce problème et vérifier que les résultats sont conformes avec la solution fournie.
void main() {
char OP;
point a(3,7), b (4, 4) ;
cout << " Donnez un Operateur +, - ou *: ";
cin >> OP;
switch (OP){
case '+' : (a + b).affiche();
cout << endl; break;
case '-' : (a - b).affiche();
cout << endl; break;
case '*' : (a * b).affiche();
cout<< endl; break;
}
}
7, 11
-1, 3
12, 28
class point {
private : int x, y;
public :
point(int a, int b){ x=a; y =b; }
point operator+(??);
point operator-(??);
point operator*(??);
void affiche();
};
Surcharge des opérateurs
P.A._IG Ch - 50M. BENJELLOUN : 2020-21
#include <iostream>
using namespace std ;
class point {
private : int x, y;
public :
point(int a, int b) { x=a; y =b; }
point operator+(point Pt);
point operator-(point Pt);
point operator*(point Pt);
void affiche(){
cout << x << " " << y << endl;
}
};
point point::operator+(point Pt) {
point p(1,1);
p.x = x + Pt.x; p.y = y + Pt.y; return p;
}
point point::operator-(point Pt) {
point p(1,1);
p.x = x - Pt.x; p.y = y - Pt.y; return p;
}
point point::operator*(point Pt) {
point p(1,1);
p.x = x * Pt.x; p.y = y * Pt.y; return p;
}
int main() {
char OP;
point a(3,7), b (4, 4) ;
cout << " Donnez un Operateur +, - ou *: ";
cin >> OP;
switch (OP){
case '+' : (a + b).affiche();cout << endl; break;
case '-' : (a - b).affiche();cout << endl; break;
case '*' : (a * b).affiche();cout<< endl; break;
}
return 0;
}
7, 11
-1, 3
12, 28
Surcharge des opérateurs
26
P.A._IG Ch - 51M. BENJELLOUN : 2020-21
Pour améliorer la réutilisabilité des morceaux de code → code générique →un module générique pas directement utilisable : un modèle, patron (template)de module qui sera "instancié" par les types de paramètres qu’il accepte.
Les patrons de fonctions
Un patron de fonction constitue une définition générique s’appliquant à des types de données différents.
template <class T>T min (T a, T b) {
if ( a < b) return a;else return b;
}
T peut être int, float, char, …
Les patrons : Fonctions et classes
P.A._IG Ch - 52M. BENJELLOUN : 2020-21
#include <iostream>
using namespace std ;
// création d'un patron de fonctions
template <class T>T min (T a, T b) {
if (a < b) return a ; // ou return a < b ? a : b ;
else return b ;}
void main() {
cout << "min (2, 9) = " << min (2, 9) << "\n" ; // int min(int, int)
cout << "min (2.3, 5.2) = " << min (2.3, 5.2) << "\n" ; // float min (float, float)
cout << "min (z, c) = " << min ('z', 'c') << "\n" ; // char min (char, char)
}
Patron de fonctions
min (2, 9) = 2
min (2.3, 5.2) = 2.3
min (z, c) = c
template <class T> T min( T x, T y, T z ) { // minimum de 3 valeurs
return min( min(x,y), z ) ;
}
Les patrons
27
P.A._IG Ch - 53M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
using namespace std ;
// création d'un patron de fonctions
template <class T>
void Saisie (T Tab, int N) ; {
for (int i = 0; i <N; i++){
cout << "\n Tab[" << i <<"] =" ;
cin >> ;Tab[i];
}
}
template <class T> ;
void Affiche (T Tab, int N) ;{
for (int i = 0; i <N; i++){
cout << "\n Tab[" << i <<"] =" ;
cout << Tab[i];
}
}
int main() {
int Vect1[10];
float Vect2[10];
string Vect3[10];
int N =5;
Saisie(Vect1, N);
Affiche(Vect1, N);
Saisie(Vect2, N);
Affiche(Vect2, N);
Saisie(Vect3, N);
Affiche(Vect3, N);
return 1;
}
Les patrons
Patron de fonctions
P.A._IG Ch - 54M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
using namespace std ;
// création d'un patron de fonctions
template <class T, class T1, class T2> T2 Fonct (T A, T1 N, T2 S) {
cout << A << " ";cout << N << " ";return S;
}
int main() {
cout << Fonct(2, 5.2, "Cool") << endl;
cout << Fonct("Lou", 'c', 19) << endl;
cout << Fonct(0.1, 0.1, 0.1) << endl;
return 1;
}
2 5.2 CoolLou c 190.1 0.1 0.1
Les patrons
Exécution
Patron de fonctions
28
P.A._IG Ch - 55M. BENJELLOUN : 2020-21
6.2. Complétez (??) dans le programme afin de créez deux patrons de fonctions dont l’un permet d’afficher les éléments et l’autre de calculer et retourner la somme d’un tableau d’éléments de type quelconque. #include <iostream>
using namespace std ;
void main(){
int ti[5] = {1, 2, 3, 4, 5} ;
float tf[5] = {1.2, 3.4, 4.5, 6.7} ;
char tc[] = { 'H', 'E', 'L', 'L', 'O' } ;
Affiche (ti, 5); cout << somme (ti, 5) << "\n" ;
Affiche (tf, 4); cout << somme (tf, 4) << "\n" ;
Affiche (tc, 5); cout << somme (tc, 5) << "\n" ;
}
1 2 3 4 5 = 151.2 3.4 4.5 6.7 = 15.8H E L L O = t
?? Affiche (?? tab[], ?? N) {
for (int i=0 ; i< N ; i++)
cout << tab[i] << " ";
cout << " = " ;
}
?? somme (?? tab[], ?? N) {
?? som =0;
for (int i=0 ; i< N ; i++)
som = som + tab[i] ;
return som ;
}
Exécution
Les patrons
P.A._IG Ch - 56M. BENJELLOUN : 2020-21
Plusieurs classes similaires pour décrire un même concept → définir des classes template
Les coordonnées d'un point de type int, float, double, long …
#include <iostream>
#include <string>
using namespace std ;
template <class T> class Duo { // patron de classe
T x , y ;
public :
Duo (T a=0, T b=0) {
x = a ; y = b ;
}
void affiche () ;
};
template <class T> void Duo <T>::affiche () {
cout << "Paire : " << x << " " << y << "\n" ;
}
void main () {
Duo <int> ai (3, 5) ; ai.affiche ();
Duo <char> ac ('d', 'y') ; ac.affiche ();
Duo <double> ad (3.5, 2.3) ; ad.affiche ();
Duo <string> as ("Salut", " A vous") ; as.affiche();
}
Paire : 3 5Paire : d yPaire : 3.5 2.3Paire : Salut A vous
Les patrons
Exécution
Patron de Classes
29
P.A._IG Ch - 57M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
using namespace std ;
template <class T> class point { // Création d'un patron de classeT x ; T y ;
public :
point (T abs=0, T ord=0) { x = abs ; y = ord ; }
void affiche () ;
T min () { // Création d'un patron de fonctionif ( x < y) return x;
else return y;
}
};
template <class T> void point<T>::affiche () {
cout << "Paire : " << x << " " << y << "\n" ;
}
void main () {
point <int> ai (3, 5) ; // T prend la valeur int pour la classe point
ai.affiche() ;
cout << " Min : ... " << ai.min() << endl;
point <char> ac ('z', 't') ; ac.affiche() ;
cout << " Min : ... " << ac.min() << endl;
point <double> ad (1.5, 9.6) ; ad.affiche() ;
cout << " Min : ... " << ad.min() << endl;
point <string> as ("Salut", " A vous") ; as.affiche() ;
cout << " Min : ... " << as.min() << endl;
}
Paire : 3 5Min : ... 3
Paire : z tMin : ... t
Paire : 1.5 9.6Min : ... 1.5
Paire : Salut A vousMin : ... A vous
Les patrons
Exécution
P.A._IG Ch - 58M. BENJELLOUN : 2020-21
class Etudiant{
string Nom, Prenom;
int Id;
float taille;
public:
//...
}
class PROF{
int Id, matricule;
string Nom;
string Service;
public:
//...
}
class Personne{
T A, B;
U C;
V D;
public:
//...
}
Les patrons
Patron de Classes
30
P.A._IG Ch - 59M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
using namespace std ;
template <class T, class T1, class T2> class Etudiant{
T Nom;
T1 Id;
T2 Age;
public:
//...
T getNom(){return Nom;}
T1 getId(){return Id;}
T2 getAge();
void Saisie();
void affiche();
//...
};
template <class T, class T1, class T2>
T2 Etudiant<T,T1,T2>::getAge(){
return Age;
}
template <class T, class T1, class T2>
void Etudiant<T,T1,T2>::Saisie(){cout<<"Veuillez entrer son nom: ";
getline(cin, Nom);
cout<<"Veuillez entrer son Id: ";
cin >> Id;
Age=18;
}
template <class T, class T1, class T2>
void Etudiant<T, T1, T2>::affiche () {cout << "Data : " << Nom << " "
<< Id << " " << Age <<"\n" ;
}
void main () {
Etudiant<string, char, int> E1;E1.Saisie();
E1.affiche();
Etudiant<string, string, int> E2;E2.Saisie();
E2.affiche();
} Complément de l’exemple du syllabus page 80
Les patrons
Patron de Classes
P.A._IG Ch - 60M. BENJELLOUN : 2020-21
Les membres privés d’une classe ne sont pas accessibles par des fonctions nonmembres. C’est la base même de la protection des données qui fait une grandepartie de la puissance de la programmation par objets.
MaisDans certains cas, il peut être intéressant d’accorder des accès aux attributs ou aux méthodes à certaines classes clientes, tout en protégeant ce même accès vis-à-vis des autres classes.
Les amis friend
Comment faire si l’on souhaite qu’une fonction f() et/ou une classe Bpuisse accéder aux données membres privées d’une classe A?
→ déclarer dans la classe A que f() et/ou B sont amies (friend) de A
Amies : fonctions et classes
Amies
31
P.A._IG Ch - 61M. BENJELLOUN : 2020-21
→déclarer dans la classe A que f()
et/ou B sont amies de A
class A {
private:
int i; … // tout ce qui est nécessaire à A…
friend class B;
// B est autorisée :classe amie
friend void f(..);
// f() est autorisée : fonction amie;
// pas membre de la classe A
};
class B {
… // tout ce qui appartient à B,
// et qui peut se servir des
// données membres privées de A
…
};
void f(..) { ..; }
L’emploi de friend donne aux fonctions, classes amies les mêmes privilèges que ceux des fonctions membres. !!!
#include <iostream>
using namespace std ;
class Objet {
int tab[20], nbr;
friend void afficher(Objet t);public:
Objet (int N){nbr = N;
for (int i = 0; i < nbr; i++)
tab[i]=i;
}
};
void afficher(Objet t) {for (int i = 0; i < t.nbr; i++)
cout << ' ' << t.tab[i];
}
void main() {
Objet T(5);
afficher(T);
}
Fonction amie
0 1 2 3 4
Amies
P.A._IG Ch - 62M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
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
}
};
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
Classe amie
Amies
32
P.A._IG Ch - 63M. BENJELLOUN : 2020-21
Modélisation !!??
Écrire la classe Etudiant. Le programme doit gérer en boucle le menu suivant :Saisie d’1 tableau Tab1 d’Etudiant de 1ère + AffichageSaisie d’1 tableau Tab2 d’Etudiant de 2ème + AffichageFusion dans un tableau dynamique les tableaux Tab1 et Tab2 +Affichage
Écrire un programme qui gère un ensemble de Profs et d’étudiants (Nmax=10).Caractéristiques des Prof(s) :
string Nom, prénom;void saisie();void afficher();
Caractéristiques des Etudiant(s) :string Nom, prénom;void saisie();void afficher();
P.A._IG Ch - 64M. BENJELLOUN : 2020-21
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.
Permet l’extension 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.
classe de base
classes dérivées
"est un" .
L’héritage
33
P.A._IG Ch - 65M. BENJELLOUN : 2020-21
classes dérivées
Principe de l’héritage
Dans la définition de la classe dérivée, afin d’utiliser l’héritage, on ajoute le symbole :après le nom de la classe en précisant par la suite quelle est la classe de base.
class ClasseDerivee : ModeDeriv ClasseBase { ... }
class Etudiant : public Personne { ... }
class Rectangle : public Point { ... }Personne
Etudiant
classe de base
Héritage
P.A._IG Ch - 66M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
using namespace std ;
class point {
private :
int x, y;
public :
void initialise(int, int) ;
void affiche(string) ;
};
class Pixel : public point { // Pixel dérive de point
int couleur ;
public :
void colore (int cl) {
couleur = cl;
cout << "\n --- couleur = " << couleur << "\n" ;
}
};
void point::initialise (int abs, int ord) {
x = abs ; y = ord ;
}
void point::affiche (string S) {
cout << S << ":- Je suis en " << x << " " << y << "\n" ;
}
int main() { point a; // objet de type class point
Pixel PC ; // objet de type class Pixel
a.initialise (3, 7) ; a.affiche ("point") ;
PC.initialise (10,20) ; PC.colore (5) ; PC.affiche("Pixel") ;
return 1;}
point:- Je suis en 3 7--- couleur = 5Pixel:- Je suis en 10 20
Héritage
Exécution
34
P.A._IG Ch - 67M. BENJELLOUN : 2020-21
class Personne {
int id;
string nom;
public:
Personne(){…}
…
};
class Etudiant : public Personne {
public: …
};
class Prof : public Personne {
...
};
…
Les classes Etudiant et Prof sont des
Personnes avec de nouvelles
fonctionnalités. Elles héritent des
champs et méthodes de Personne et
possèdent en plus des champs
spécifiques.
Héritage Public: les types d’attributs
class Base {
public: void pub1();
protected: void prot1();
private: void priv1();
};
class Deriv : public Base {
public:
void pub2() {
pub1(); // OK
prot1(); // OK
priv1(); // ERREUR
}
};
Base X;
X.pub1(); // OK
X.pub2(); // Erreur
Deriv Y;
Y.pub1();
Y.pub2();
Y.priv1(); // Erreur
Y.prot1(); // Erreur
Héritage
L’accès aux membres d’une classe peut être, soit :
◮ public (public) : visibilité totale à l’intérieur et à l’extérieur de la classe
◮ privé : visibilité uniquement à l’intérieur de la classe (mot-clé private ou par défaut)
Mais l’accès aux attributs/méthodes au sein d’une hiérarchie de classes :
◮ protégé (protected): assure la visibilité des membres d’une classe dans les classes de sa descendance.
P.A._IG Ch - 68M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
using namespace std ;
class point {
private : int x,;y;
public :
void initialise(int, int) ;
void affiche() ;
};
void point::initialise (int abs, int ord) {
x = abs ; y = ord ;
}
void point::affiche () {
cout << ":- Je suis en " << x << " " << y << "\n" ;
}
class Pixel : ;public point {
int couleur ;
public :
void colore (int cl) { couleur = cl ; }
void afficheP () ;
void initialiseP (int, int, int) ;
} ;
void Pixel::afficheP () {
affiche (;) ;
cout << " et ma couleur est : " << couleur << "\n" ;
}
void Pixel::initialiseP ;(int abs, int ord, int cl) {
initialise (abs, ord) ;
couleur = cl ;
}
void main(){
Pixel p ;
p.initialiseP (10, 20, 5) ;
p.afficheP () ;
p.affiche () ;
p.colore (2) ;
p.afficheP () ;
} :- Je suis en 10 20et ma couleur est : 5
……
Héritage
Héritage Public: les types d’attributs
35
P.A._IG Ch - 69M. BENJELLOUN : 2020-21
#include <iostream>
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();
}
Redéfinition des fonctions membres dans la classe dérivée
In F2 XIn F1 X…
protégés (protected) = accessibles aux membres de la classe et de ses classes dérivées.
Héritage
MASQUAGE
P.A._IG Ch - 70M. BENJELLOUN : 2020-21
#include <iostream>
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 Pixel : public point {
int couleur ;
public :
Pixel (int, int, int) ; // déclaration constructeur Pixel
} ;
Pixel :: Pixel (int abs=1, int ord=2, int cl=3)
{ cout << "++ constr. Pixel : " << abs << " " << ord << " " << cl << "\n" ;
couleur = cl ;
}
void main() {
Pixel a(10,15,3);
}
Héritage Constructeurs
++ constr. point : 0 0++ constr.Pixel : 10 15 3
Héritage
Exécution
36
P.A._IG Ch - 71M. BENJELLOUN : 2020-21
#include <iostream>
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 Pixel : public point {
int couleur ;
public :
Pixel (int, int, int) ; // déclaration constructeur Pixel
} ;
Pixel :: Pixel (int abs=1, int ord=2, int cl=3) : point (abs, ord)
{ cout << "++ constr. Pixel : " << abs << " " << ord << " " << cl << "\n" ;
couleur = cl ;
}
void main() {
Pixel a(10,15,3);
}
Héritage Constructeurs
++ constr. point : 0 0++ constr.Pixel : 10 15 3
Héritage
Exécution
P.A._IG Ch - 72M. BENJELLOUN : 2020-21
#include <iostream>
using namespace std ;
class base {
public:
base(){ cout <<"construction de la base \n;}
~base(){ cout <<"destruction de la base \n;}
};
class derive : public base{
public:
derive() { cout << "construction de la dérivée \n";}
~derive() {cout << "destruction de la dérivée \n";}
};
void main() {
derive o;
}
construction de la base construction de la dérivée destruction de la dérivée destruction de la base
Héritage Constructeurs et destructeurs
Héritage
Exécution
37
P.A._IG Ch - 73M. BENJELLOUN : 2020-21
Héritage Constructeurs et destructeurs#include <iostream>
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 Pixel : public point {
int couleur ;
public : Pixel (int, int, int) ; // déclaration constructeur pointcol
~Pixel () // destructeur de pointcol ("inline")
{ cout << "-- dest. Pixel - couleur : " << couleur << "\n" ; }
} ;
Pixel::Pixel (int abs=0, int ord=0, int cl=1) : point (abs, ord)
{ cout << "++ constr. Pixel : " << abs << " " << ord << " " << cl <<
"\n" ;
couleur = cl ;
}
void main() {
Pixel a(10,15,3) ; // objets
Pixel c (12) ; // automatiques
Pixel * adr ;
adr = new Pixel (12,25) ; // objet dynamique
delete adr ;
}
++ constr. point : 10 15++ constr. Pixel : 10 15 3++ constr. point : 12 0++ constr. Pixel : 12 0 1++ constr. point : 12 25++ constr. Pixel : 12 25 1-- dest. Pixel - couleur : 1-- destr. point : 12 25-- dest. Pixel - couleur : 1-- destr. point : 12 0-- dest. Pixel - couleur : 3-- destr. point : 10 15
Héritage
Exécution
P.A._IG Ch - 74M. BENJELLOUN : 2020-21
Le polymorphisme est implémenté en C++ à l'aide des fonctions virtuelles.Il permet grâce à la dérivation qu'un pointeur sur une classe dérivée soit "type-compatible" avec un pointeur sur sa classe de base.
On peut déclarer des fonctions dans une classe de base qui pourront être redéfinies dans chaque classe dérivée. Le compilateur garantira la bonne correspondance entre les objets et les fonctions s'y appliquant. On définit une fonction virtuelle avec le mot clef « virtual ».
Notion de polymorphisme – fonctions virtuelles
IntérêtLe polymorphisme permet de déclarer une seule variable de type pointeur (ou de référence) pour un ensemble d’objets issus d’une hiérarchie de classes et de choisir à l’exécution du programme le type d’objet à créer.
38
P.A._IG Ch - 75M. BENJELLOUN : 2020-21
Constructeur classe mereConstructeur classe mereConstructeur classe filleLa mere: GetNom : classe mereLa fille: GetNom : classe fille
#include<iostream>using namespace std;
class Mere {public:
Mere(){ cout << "Constructeur classe mere\n"; }void GetNom() { cout << " GetNom : classe mere\n"; }void Affiche() { GetNom(); }
};
class Fille : public Mere {public:Fille() { cout << "Constructeur classe fille\n"; }void GetNom(){ cout << "GetNom : classe fille\n"; }
};
void main() {
Mere m;
Fille f;
cout << "La mere: ";
m.Affiche();
cout << "La fille: ";
f.Affiche();
}
Constructeur classe mereConstructeur classe mereConstructeur classe filleLa mere: GetNom : classe mereLa fille: GetNom : classe mere
Avec virtual
Sans virtual
virtual
Polymorphisme
P.A._IG Ch - 76M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
using namespace std;
class Base {
public: virtual void affiche();
};
class B1 : public Base {
public: void affiche();
};
class B2 : public Base {
public: void affiche();
};
void Base::affiche(){
cout << "Base" << endl;
}
void B1::affiche(){
cout << "B1 : Derive1" << endl;
}
void B2::affiche(){
cout << "B2 : Derive2" << endl;
}
void print(Base *instance){
instance->affiche();
}
void main( ) {
Base objB ;
B1 objD1;
B2 objD2;
print(&objB);
print(&objD1);
print(&objD2);
}
BaseB1 : Derive1B2 : Derive2
BaseBaseBase
virtual
Polymorphisme
39
P.A._IG Ch - 77M. BENJELLOUN : 2020-21
STLLa STL ("Standard Template Library") est une librairie de
= classes containers + iterateurs + algorithmes
P.A._IG Ch - 78M. BENJELLOUN : 2020-21
La bibliothèque standard (C++11) est formée de 79 « paquets » : ◮ 33 « classiques » (C++98), exemple
◮ 20 nouveaux (C++11 ) , exemple
◮ 26 bibliothèques C (C99) , exemple
<algorithm> plusieurs algorithmes utiles
<complex> les nombres complexes
<deque> tableaux dynamiques avec push_front
<exception> diverses fonctions aidant à la gestion des exceptions
<fstream> manipulation de fichiers
<iomanip> manipulation de l’état des flots
<iostream> flots standards
<map> tables associatives clé–valeur ordonnées
<numeric> fonctions numériques
<ostream> flots de sortie
<queue> files d’attente
<set> ensembles ordonnés
<string> chaînes de caractères
<typeinfo> information sur les types
<vector> tableaux dynamiques
<array> tableaux de taille fixe <chrono> heures et chronomètres <forward_list> listes simplement chaînées<random> nombres aléatoires <unordered_map> tables associatives non ordonnées <unordered_set> ensembles non ordonnés
<cmath> diverses définitions mathématiques <ctime> diverses conversions de date et heures
STL
40
P.A._IG Ch - 79M. BENJELLOUN : 2020-21
Conteneurs (containers) : collections d'objets très efficaces : vecteurs, listes chaînées, …
STL
Conteneuriterator begin()iterator end()
bool empty…
Séquence
vector list deque
Associatif
map multimap set multiset
Paramétrés par la clé et la valeur Paramétrés par la clé
Itérateurs (Iterators) ; fonctionnalités pour parcourir les éléments qui se retrouvent dans les conteneurs.
Algorithmes : patrons de fonctions utilisés pour faire des traitements sur les éléments
qui se retrouvent dans les conteneurs.
= classes containers + iterateurs + algorithmes
STL
P.A._IG Ch - 80M. BENJELLOUN : 2020-21
Conteneurs (containers) : collections d'objets très efficaces : vecteurs, listes chaînées, …
STL
Conteneuriterator begin()iterator end()
bool empty…
Séquence
vector list
Itérateurs (Iterators) ; fonctionnalités pour parcourir les éléments qui se retrouvent dans les conteneurs.
Algorithmes : patrons de fonctions utilisés pour faire des traitements sur les éléments
qui se retrouvent dans les conteneurs.
= classes containers + iterateurs + algorithmes
STL
41
P.A._IG Ch - 81M. BENJELLOUN : 2020-21
Headers <array> <vector> <deque> <forward_list> <list>
Members array vector deque forward_list list
constructor implicit vector deque forward_list list
destructor implicit ~vector ~deque ~forward_list ~list
operator= implicit operator= operator= operator= operator=
iterators
begin begin begin begin
begin before_begin
begin
end end end end end end
rbegin rbegin rbegin rbegin
rbegin
rend rend rend rend
rend
const iterators
cbegin cbegin cbegin cbegin
cbegin
cbefore_begin cbegin
cend cend cend cend cend cend
crbegin crbegin crbegin crbegin
crbegin
crend crend crend crend
crend
capacity
size size size size
size
max_size max_size max_size max_size max_size max_size
empty empty empty empty empty empty
resize resize resize resize resize
Fonctions membres
STL
P.A._IG Ch - 82M. BENJELLOUN : 2020-21
Headers <array> <vector> <deque> <forward_list> <list>
Members array vector deque forward_list list
element access
front front front front front front
back back back back
back
operator[] operator[] operator[] operator[]
at at at at
modifiers
assign assign assign assign assign
emplace emplace emplace emplace_after emplace
insert insert insert insert_after insert
erase erase erase erase_after erase
emplace_back emplace_back emplace_back
emplace_back
push_back push_back push_back
push_back
pop_back pop_back pop_back
pop_back
emplace_front emplace_front emplace_front emplace_front
push_front push_front push_front push_front
pop_front pop_front pop_front pop_front
clear clear clear clear clear
swap swap swap swap swap swap
list operations
splice splice_after splice
remove remove remove
remove_if remove_if remove_if
unique unique unique
merge merge merge
sort sort sort
reverse reverse reverse
observers get_allocator get_allocator get_allocator get_allocator get_allocator
data data data
STL
Fonctions membres
42
P.A._IG Ch - 83M. BENJELLOUN : 2020-21
Le template Vector
Constructeursvector<T> v; default constructor
vector<T> v(int); initialized with explicit size
vector<T> v(int, T); size and initial value
vector<T> v(aVector); copy constructor
Accès aux élémentsv[i] subscript access (not safe)
v.at(i) subscript access (safe)
v.front() first value in collection
v.back() last value in collection
Insertionv.push_back(T) push element on to back of vector
v.insert(iterator, T) insert new element after iterator
v.swap(vector<T>) swap values with another vector
Suppressionv.pop_back() pop element from back of vector
v.erase(iterator) remove single element
v.erase(iterator, iterator) remove range of values
Taillev.capacity() number of elements buffer can hold
v.size() number of elements currently held
v.resize(unsigned, T) change to size, padding with value
v.reserve(unsigned) set physical buffer size
v.empty() true if vector is empty
Itérateursvector<T>::iterator itr declare a new iterator
v.begin() starting iterator
v.end() ending iterator
Fonctions membres
STL
(vector)
expression Autre sémantique conteneur
a.front() *a.begin() vector, list
a.back() *a.(--end()) vector, list
a.push_front(t) a.insert(a.begin(), t) list
a.push_back(t) a.insert(a.end(), t) vector, list
a.pop_front() a.erase(a.begin()) list
a.pop_back() a.erase(--a.end()) vector, list
a[n] *(a.begin() + n) vector
P.A._IG Ch - 84M. BENJELLOUN : 2020-21
Les listes
Constructeurs et affectationlist<T> v; default constructor
list<T> v (aList); copy constructor
l = a List assignment
l.swap (aList) swap values with another list
Accès aux élémentsl.front () first element in list
l.back () last element in list
Insertion et suppressionl.push_front (value) add value to front of list
l.push_back (value) add value to end of list
l.insert (iterator, value) insert value at speci_ed location
l.pop_front () remove value from front of list
l.pop_back () remove value from end of list
l.erase(iterator) remove referenced element
l.erase(iterator,iterator) remove range of elements
l.remove (value) remove all occurrences of value
l.remove_if (predicate) removal all values that match condition
Taillel.empty () true if collection is empty
l.size () return number of elements in collection
Itérateurslist<T>::iterator itr declare a new iterator
l.begin () starting iterator
l.end () ending iterator
Diversl.reverse () reverse order of elements
l.sort () place elements into ascending order
l.sort (comparison) order elements using comparison function
l.merge (list) merge with another ordered list
Fonctions membres
STL
(list)
43
P.A._IG Ch - 85M. BENJELLOUN : 2020-21
iterator begin();
const_iterator begin() const; // Itérateur sur le premier élément.
iterator end();
const_iterator end() const; // Itérateur au-delà du dernier élément.
reverse_iterator rbegin();
const_reverse_iterator rbegin() const; // Itérateur rétrograde sur le dernier élément.
reverse_iterator rend();
const_reverse_iterator rend() const; // Itérateur rétrograde au-delà du premier élément.
reference front();
const_reference front() const; // Référence au premier élément.
reference back();
const_reference back() const; // Référence au dernier élément.
STL
Les accesseurs
P.A._IG Ch - 86M. BENJELLOUN : 2020-21
Les méthodes size_t size() const; // Nombre d’éléments.
void push_back(const T& x); // Ajoute l’élément x en fin de vecteur.
void pop_back(); // Supprime le dernier élément du vecteur.
iterator insert(iterator position, const T& x); // Insert l’élément x devant l’élément désigné par position.
iterator insert(iterator position);// Insert un élément construit par défaut devant l’élément désigné par position.
void insert(iterator position, const_iterator first, const_iterator last);// Insert une séquence d’élément désigné par first et last devant l’élément désigné par position.
iterator erase(iterator position); // Efface l’élément à la position donnée.
iterator erase(iterator first, iterator last); // Efface les éléments entre first et last exclus.
void clear(); // Efface tous les éléments du vecteur.
Les méthodes spécifiques
T back()Valeur du dernier élément .
T front()Valeur du premier élément.
STL
44
P.A._IG Ch - 87M. BENJELLOUN : 2020-21
Les conteneurs
Vector Le but de cette classe est de généraliser la notion de tableau. Sa structure interne est un tableau dynamique qui est redimensionnable, automatiquement ou manuellement.
La classe vector en C++
Pour utilisér la classe vector, il faut inclure le fichier vector.
#include <vector>
Les principales méthodes de cette classe.
Les constructeurs
vector();
vector(size_t n);Vecteur de n éléments.
vector(const vector<T>& x);Constructeur par copie.
…
STL
P.A._IG Ch - 88M. BENJELLOUN : 2020-21
Il est aussi possible d'initialiser un vecteur rempli d'un certain nombre d'éléments.
vector<int> v(10); // v contient 10 élémentsfor (int i=0; i<10; i++) v[i] = i;
vector<int> v;for (int i=0; i<100; i++)
v.push_back(i); // insérer un nouvel élément à la fin du container
// 0 1 2 3 4 5 ...
for (int i=0; i<v.size(); i++) // size() retourne le nombre d’éléments dans le tableau
cout << v[i] << ' ';
0 1 2 3 4 5
STL
45
P.A._IG Ch - 89M. BENJELLOUN : 2020-21
#include <vector>
#include <iostream>
using namespace std;
void main() {
int MAX=10;
//créer un vecteur qui stocke MAX entiers
vector<int> Tab(MAX);
//remplir vecteur
for (int i=0; i<MAX; i++) {
Tab[i] = i+1;
}
//afficher vecteur de MAX-1
for (int i=Tab.size()-1; i>=0; i--) {
cout <<Tab [i] <<endl;
}
}
10
9
8
7
6
5
4
3
2
1
Utilisation du conteneur séquentiel vector
affiche(Tab);
void affiche(vector<int> T ){
for (int i=T.size()-1 ; i>=0; i--)
cout <<T[i] << " "<< endl;
}
STL
P.A._IG Ch - 90M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<int> V0;
affiche(V0, " (V0 ): ");
V0.push_back(9);
affiche(V0, " (V0+): ");
int dim=6 ;
vector<int> V1(dim);
affiche(V1, " (V1 ): ");
int Valeur = 2;
vector<int> V2(dim, Valeur);
affiche(V2, " (V2 ): ");
vector<int> V3(V2);
affiche(V3, " (V3 ): ");
return 0;
}
(V0 ): size = 0 Data :
-------------
…
…
void affiche(vector<int> T, string Nom) ;{
cout << Nom<<" : size = " << T.size() << " Data :";
for (int i=0; i<T.size(); i++)
cout <<T[i] << " ";
cout << " ------------- " <<endl;
}
STL
46
P.A._IG Ch - 91M. BENJELLOUN : 2020-21
Utilisation du conteneur séquentiel vector
#include <vector>#include <iostream>
using namespace std;
void affiche(vector<int> T){
for (int i=0; i<T.size(); i++)
cout <<T[i] << " ";
cout << endl << "size = " << T.size()<<endl;
}
int main() {
vector<int> Tab(6);
for (int i=0; i<6; i++) ; Tab[i]= i ;
affiche(Tab);
Tab.pop_back();
affiche(Tab);
Tab.pop_back();
affiche(Tab);
return 0;
}
0 1 2 3 4 5size = 6
0 1 2 3 4...
STL
P.A._IG Ch - 92M. BENJELLOUN : 2020-21
Les matrices
Une matrice peut être vue comme un vecteur de vecteurs.• Exemple :
Matrice d'entier 3 × 4vector < vector<int> > mat(3);
• Il faut allouer de l'espace mémoire pour chaque ligne
for (int i = 0; i < mat.size(); i++)mat[i].resize(4);
STL
47
P.A._IG Ch - 93M. BENJELLOUN : 2020-21
list
La liste est une liste dynamique doublement chaînée et propose un ajout et une suppression en début de liste.
list<int> Liste1; // liste d'entiers vide
list<int> Liste2(5, 77); // construite avec 5 éléments de type int ayant tous la valeur 77
Liste2.front(); // Retourne la valeur en tête de liste
Liste2.back(); // Retourne la valeur en queue de liste
PRÉCÉDENT
SUIVANT
Objet T
PRÉCÉDENT
SUIVANT
Objet T
PRÉCÉDENT
SUIVANT
Objet T
front back
L’opérateur [i] n’est pas disponible sur les objets de type list. L’accès aux éléments ainsi que l'ajout et la suppression en milieu de listesont rendus possibles par l'intermédiaire des itérateurs.
STL
P.A._IG Ch - 94M. BENJELLOUN : 2020-21
#include <list>#include <iostream>
using namespace std;
void main() {list<int> L;
//Ajouter des valeurs a la fin de la liste
L.push_back(33);
cout <<L.front() <<endl;
L.push_back(15);
cout <<L.back() <<endl;
L.push_back(44);
cout <<L.back() <<endl;
L.push_front(99);
cout <<L.front() <<endl;
//Supprimer des valeurs de la liste
L.pop_back();
cout <<L.back() <<endl;
L.pop_front();
cout <<L.front() <<endl;}
Utilisation du conteneur séquentiel list
33
33 15
33
15
4433 15 44
STL
…
48
P.A._IG Ch - 95M. BENJELLOUN : 2020-21
#include <list>
#
…
int main() {
list<int> L1;
list<int> ::iterator it ;
int n;
cout << "donnez 5 entiers : ";
for (int i=0 ; i<5 ; i++) {
cin >> n ;
L1.push_front(n);
}
Affiche_L(it, L1, " Liste : ");
while (!L1.empty() ) {
L1.pop_back();
Affiche_L(it, L1, " Liste : ");
}
return 0;
}
Donnez 5 entiers : 1 2 2 3 4Liste : : 4 3 2 2 1……!!??
P.A._IG Ch - 96M. BENJELLOUN : 2020-21
Les itérateurs
vector<int> V ; // tableau vide sans dim
list<int> Liste; // une liste vide
list<int> :: iterator it ; // itérateur direct
vector<int> :: iterator iV ;
vector<int>::reverse_iterator rp; // parcours du vecteur en sens inverse
Les itérateurs portant le nom iterator (même reverse_iterator …) sont des pointeurs spécialisés qui accèdent aux éléments d'un conteneur.
for (it= Liste.begin() ; it != Liste.end() ; it++)
cout << *it << " "; // *it désigne l'élément courant de la liste
for (iV=V.begin(); iV !=V.end(); iV++)
cout<<*iV<<" ; " ;
L’iterator est doté d’une méthode begin qui renvoie un itérateur sur le premier de ses éléments, et d’une méthode end qui renvoie un itérateur sur une place se trouvant juste après le dernier élément.
for (rp=V.rbegin(); rp!=V.rend(); rp++)
cout<<*rp<<" ; " ;
// + de .size()
STL
49
P.A._IG Ch - 97M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;
void affiche(vector<int> V) ;{
cout << "VECTOR" << " : ";
for (int i=0; i< V.size() ; i++) {
cout <<V[i] <<" ";}
cout << endl;}
void print(list<int>::iterator it, list<int> ;; L, string S){
cout << S << " : ";for (it= L.begin() ; it != L.end() ; it++) {
cout << *it << " ";// *it : élém courant de liste
}
cout << endl;
}
void main() {
vector<int> Tab; // tableau vide sans dim
list<int> Liste1, Liste2; // deux listes vides
list<int> ::iterator it ; // itérateur directint i=0;
// Saisie des entiers
cout << "Saisir Entier (-1 pour finir) : ";
cin >> i;
while (i != -1) {
Tab.push_back(i);
Liste1.push_back(i);
Liste2.push_front(i);cout << "Saisir Entier (-1 pour finir) : ";
cin >> i;
}
// Affichage des données
affiche(Tab);
print( it, Liste1, "LISTE1");
print( it, Liste2, "LISTE2");}
Saisir Entier (-1 pour finir) : 1Saisir Entier (-1 pour finir): 2Saisir Entier (-1 pour finir): 3Saisir Entier (-1 pour finir): 4Saisir Entier (-1 pour finir): 5Saisir Entier (-1 pour finir): -1VECTOR : 1 2 3 4 5… Programme 8.1.voir?
STL
P.A._IG Ch - 98M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include ; <list>
using namespace std ;
void main() {
char c[6]={'a','b','d','d','e'};
list<char> c1;
list<char>::iterator itc;
for(int i=0; i<5; i++)
c1.push_back(c[i]);
print(itc, c1, "Liste c1 ");
itc=c1.begin();
itc++; *itc='A';
print(itc, c1, "Liste c1 ");
itc=c1.begin();
itc++; itc++; c1.insert(itc,3,'B');
print(itc, c1, "Liste c1 ");
c1.remove('d');
print(itc, c1, "Liste c1 ");
}
void print(list<char>::iterator it, list<char> Liste, string S){
cout << S << " : ";
for (it= Liste.begin() ; it != Liste.end() ; it++) ; ;
; cout << *it << " ";
cout << endl;
}
Qu'affiche ce programme à l'écran ?
Que deviendra ce programme si list<char> c1; est remplacé par vector<char> v; ?
STL
50
P.A._IG Ch - 99M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include <list>
using namespace std;
void main(){
int A[6] = {9, 4, 2, 8, 1, 3};
list<int> L1;
print(L1, " (1) ");
for(int i=0; i<6; i++)
L1.push_back(A[i]);
print( L1, " (2) ");
L1.sort(;);print( L1, " (3) ");
;L1.sort(cmp);print( L1, " (4) ");
}
void print( list<int> Liste, string S){list<int>::iterator it ;
cout << S << " : ";
for (it= Liste.begin() ; it != Liste.end() ; it++) ; {
; cout << *it << " ";
}
cout << endl;
}
bool cmp( int a, int b ) {
return a > b; // sens du TRI décroissant
}
Qu'affiche ce programme à l'écran ?
Que deviendra ce programme si list<char> c1; est remplacé par vector<char> v; ?
STL
P.A._IG Ch - 100M. BENJELLOUN : 2020-21
Les listes
• Taille arbitraire, excellente gestion mémoire quand celle-ci varie beaucoup durant l'exécution du programme• Accès séquentiels uniquement, temps constant pour le premier ou le dernier élément• Insertion ou suppression efficace à toutes les positions de la liste.
STL
void saisie(vector<int> …){…v.insert(V.begin(),'K');
}
template <class A, class B>void saisie(A …,B …) {
…T.insert(V.begin(),'K');
}
void saisie(list<int> …){…v.insert(l.begin(),'K');
}
Exemple de template
51
P.A._IG Ch - 101M. BENJELLOUN : 2020-21
void affiche(vector<int> T, string S){
cout << S ;
for (int i=0; i<T.size(); i++)
cout <<T[i] << " ";
; cout << endl;
}
void print( list<int> Liste, string S){list<int>::iterator it ;
cout << S << " : ";
for (it= Liste.begin() ; it != Liste.end() ; it++) ; {
cout << *it << " ";
}
cout << endl;
}
void affiche2(vector<int> V, string S){
vector<int>::iterator it;
cout << S ;
for (it=V.begin(); it!=V.end(); ++it) ;
cout << " " << ; *it;
cout << endl;
}
STL
Patron de fonctions : template ??
Affichage(???);
P.A._IG Ch - 102M. BENJELLOUN : 2020-21
void main(){
int N1, N2;
list<Etudiant> Etuds;
vector<PROF> Profs;
Etudiant TempE;
PROF TempP;
do{ menu(choix);
if(choix==1){
saisie<vector<Prof>,Prof> (Profs, N1);
Affichage(Profs);
break;
}
else {;
saisie<list<Etudiant>,Etudiant> (Etuds, N2);
Affichage(Etuds);
break;
}
}while(choix!=3);
}
STL
void main() {
int N1, N2;
list<Etudiant> Etuds;
vector<PROF> Profs;
Etudiant TempE;
PROF TempP;
do{; menu(choix);
if(choix==1) {
saisie(Profs, TempP, N1);
Affichage(Profs);
break;
}
else {;
saisie(Etuds, TempE, N2);
Affichage(Etuds);
break;
}
}while(choix!=3);
}
template <class A, class B>void saisie(A &Tab,B temp, int &N) {
…
template <class A, class B>void saisie(A &Tab, ; int &N) {
…
52
P.A._IG Ch - 103M. BENJELLOUN : 2020-21
Algorithmes
for_eachfindfind_iffind_first_ofcountcount_ifequalsearchsearch_nfind_end
copy copy_nswap replace fillfill_ngenerateremoveunique reverserotate
sortpartial_sortnth_element lower_boundupper_bound mergeminmaxmin_element max_elementlexicographical_compare
Les algorithmes sont des patrons de fonctions dans la STL
STL
sort ( V.begin(), V.end());
sort ( V.begin(), V.end(), cmp );
it = find (L.begin(), L.end(), “Texte");
it = find (V.begin(), V.end(), “Texte");
P.A._IG Ch - 104M. BENJELLOUN : 2020-21
void affiche(vector<int> T,
string S){
cout << S ;
for (int i=0; i<T.size(); i++)
; cout <<T[i] << " ";
cout << ;endl;
}
#include <iostream>
#include <string>#include <vector>
#include <algorithm>
using namespace std;
bool cmp( int a, int b ) { // sens du TRI
return a > b;
}
void main(;){
vector<int> V(6);
int A[6] = {9, 4, 2, 8, 1, 3};
affiche(V, " (1): ");
for(int i = 0; i < 6; i++ ) V[i]=A[i];
;affiche(V," (2): ");
sort ( V.begin(), V.end());affiche(V, " (3): ");
sort ( V.begin(), V.end(), cmp );affiche(V, " (4): ");
}
(1) : 0 0 0 0 0 0
(2) : 9 4 2 8 1 3
(3) : 1 2 3 4 8 9
(4) : …
sortV. sort( );
STL
53
P.A._IG Ch - 105M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>#include <vector>
#include <algorithm>
using namespace std;
bool cmp( int a, int b ) { // sens du TRI
return a > b;
}
void main(){
vector<int> V(6);
int A[6] = {9, 4, 2, 8, 1, 3};
…
sort ( V.begin(), V.begin() + 3 );
affiche(V, " (2’): ");
sort ( V.begin(), V.end());affiche(V, " (3): ");
sort ( V.begin(), V.end(), cmp );affiche(V, " (4): ");
}
(1) : 0 0 0 0 0 0
(2) : 9 4 2 8 1 3
(2’) : 2 4 9 8 1 3
(3) : …
(4) : …
sortquicksort en nlog(n)
STL
P.A._IG Ch - 106M. BENJELLOUN : 2020-21
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
void main() {
list<int> liste;
vector<int> vecteur;
// insérer les valeurs 1 à 10 dans la liste
// Adapter la taille du vecteur à la taille de la liste
//Verser le contenu de la liste dans le vecteur
}
for (int i=1; i<10; i++) {liste.push_back(i);
}
vecteur.resize ( liste.size() );
copy (liste.begin(), liste.end(), // source
vecteur.begin()); // destination
resizecopy
54
P.A._IG Ch - 107M. BENJELLOUN : 2020-21
min_element() et max_element(): Exemple : cout << *min_element(v.begin(),v.end()) << endl;
cout << *max_element(t, t+10) << endl;
min_elementmax_element
const T& max ( const T& a, const T& b )const T& min ( const T& a, const T& b )
Exemple : cout << "max(5, 2 )=" << max(5,2); // 5
min & max
searchRechercher la séquence d’éléments [début2, fin2] et
sa position dans l’ensemble [début1,fin1]
search (Itér début1, Itér fin1, Itér début2, Itér fin2);Exemple : search(v1.begin(), v1.end(), v2.begin(), v2.end());
find() : Trouver la position de Valeur entre début et fin. Retourne comme résultat un itérateur sur cet élément.
find (Itérateur début, Itérateur fin, const Type&Valeur);Exemple : find(v.begin(),v.end(), 15);
find
STL
P.A._IG Ch - 108M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std ;
void affiche(list<string> L, string S){
list<string>::iterator it;
cout << S ;
for (it=L.begin(); it!=L.end(); it++)
cout << " " << *it;
cout << endl;}
void main() {
list<string> l;
list<string>::iterator it;
l.push_back("il"); l.push_back("fait"); l.push_back("beau");
affiche (l, "(1)");
it = find (l.begin(), l.end(), "beau");if(it != l.end())
l.insert(it, "tres");affiche (l, "(2)");
…}
(1) il fait beau
(2) il fait tres beau
(3) il tres beau
Exce8.7. Donner le code d’un programme qui crée une liste de string représentant la phrase ”il fait beau”, trouve la position du mot ”beau” et insère le mot ”tres” à la position précédente.
STL
Compléter le programme pour qu’il affiche le résultat de (3)
55
P.A._IG Ch - 109M. BENJELLOUN : 2020-21
template <class T, class T1, class T2 >
void test(T Cont, T1 It, T2 cherch, string txt){
cout << "\n Test " << txt << endl;
It = find(Cont.begin(), Cont.end(), cherch);
if ( It != Cont.end()){
cout <<*It <<" est dans "<< txt <<endl ;
}
else {
cout <<cherch<<" n'est pas dans "<< txt <<endl ;
}
}
#include <vector>
#include <list>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void main() {
vector<string> V(3);
vector<string>::iterator itV;
V[0]="V0";
V[1]="V1";
V[2]="V2";
string St1="V1", St2="V5";
test(V, itV, St1, "Vecteur");
test(V, itV, St2, "Vecteur");
list<int> L;
list<int>::iterator itL;
for( int i = 0; i < 5; i++ ) {
L.push_back(i);
}
int x=10, y=2;
test(L, itL, x, "List");
test(L, itL, y, "List");
}
Test VecteurV1 est dans Vecteur
Test VecteurV5 n'est pas dans Vecteur
Test List10 n'est pas dans List
Test List2 est dans List
8.8 En utilisant l’algorithme find de STL et les templates, donnez le code de la fonction Test pour que ce programme affiche le résultat suivant :
STL
P.A._IG Ch - 110M. BENJELLOUN : 2020-21
#include <iostream>
#include <numeric> // pour accumulate
#include <vector>
#include <list>
using namespace std;
int main() {
int tab[4] = { 3, 5, 8, 1 };
vector<int> v;
list <int> L;
for (int i = 0; i < 4; i++) {
v.insert(v.end(), tab[i]); L.insert(L.end(), tab[i]);
}
// Calculer la somme des éléments avec 0 comme valeur initiale
cout << "somme Tab= " << accumulate(tab, tab + 4, 0) << endl; // 17= 3+5+8+1 + 0
cout << "somme V= " << accumulate(v.begin(), v.end(), 0) << endl; // 17
cout << "somme L= " << accumulate(L.begin(), L.end(), 0) << endl; // 17
cout << "multip Tab= " << accumulate(tab, tab + 4, 1, multiplies<int>()) << endl; // 120= 3*5*8*1 * 1
cout << "multip V= " << accumulate(v.begin(), v.end(), 1, multiplies<int>()) << endl; // 120
cout << "multip L= " << accumulate(L.begin(), L.end(), 1, multiplies<int>()) << endl; // 120
system("pause");
return 0;
}
Exemple d’algorithme numérique (accumule) Exemple : calcule v[3] + (v[2] + (v[1] + (v[0] + 0))).
Exemple : calcule v[3] * (v[2] * (v[1] * (v[0] * 1))).
56
P.A._IG Ch - 111M. BENJELLOUN : 2020-21
Conteneurs (containers) : collections d'objets très efficaces : vecteurs, listes chaînées, …
STL
Conteneuriterator begin()iterator end()
bool empty…
Associatif
map multimap set multiset
Paramétrés par la clé et la valeur Paramétrés par la clé
Itérateurs (Iterators) ; fonctionnalités pour parcourir les éléments qui se retrouvent dans les conteneurs.
= classes containers + iterateurs + algorithmes
STL
P.A._IG Ch - 112M. BENJELLOUN : 2020-21
A partir de la clé, on accède à la valeur associée Ils sont particulièrement adaptés lorsqu'on a besoin de réaliser un grand nombre d'opérations de recherche.
On trouve quatre conteneurs associatifs (ensemble s ordonnées)
• set <K , Cmp > ; map <K, V, Cmp >
• multiset : un set acceptant des duplications d’éléments.
• multimap : un map acceptant des duplications de clés.
K= clé = identifiant ; V = Valeur
Cmp = fonction qui définit la comparaison entre deux clés.
Croissant par défaut ( set <K > ; map <K, V > ).
Le tableau associatif
STL
57
P.A._IG Ch - 113M. BENJELLOUN : 2020-21
On trouve quatre conteneurs associatifs (ensembles ordonnées)
• set <KClé, Cmp > ; map <KClé, Vvaleur, Cmp >
Cmp = fonction qui définit la comparaison entre deux clés.
Croissant par défaut ( set <K > ; map <K, V > ).
Le tableau associatif
STL
P.A._IG Ch - 114M. BENJELLOUN : 2020-21
Headers <set> <map>
Members set multiset map multimap
constructor set multiset map multimap
destructor ~set ~multiset ~map ~multimap
assignment operator= operator= operator= operator=
iterators
begin begin begin begin begin
end end end end end
rbegin rbegin rbegin rbegin rbegin
rend rend rend rend rend
const
iterators
cbegin cbegin cbegin cbegin cbegin
cend cend cend cend cend
crbegin crbegin crbegin crbegin crbegin
crend crend crend crend crend
capacity
size size size size size
max_size max_size max_size max_size max_size
empty empty empty empty empty
reserve
element access
at at
operator[] operator[]
modifiers
emplace emplace emplace emplace emplace
emplace_hint emplace_hint emplace_hint emplace_hint emplace_hint
insert insert insert insert insert
erase erase erase erase erase
clear clear clear clear clear
swap swap swap swap swap
Operations
count count count count count
find find find find find
equal_range equal_range equal_range equal_range equal_range
lower_bound lower_bound lower_bound lower_bound lower_bound
upper_bound upper_bound upper_bound upper_bound upper_bound
observers
get_allocator get_allocator get_allocator get_allocator get_allocator
key_comp key_comp key_comp key_comp key_comp
value_comp value_comp value_comp value_comp value_comp
58
P.A._IG Ch - 115M. BENJELLOUN : 2020-21
(constructor) Construct map
(destructor) Map destructor
operator= Copy container content
Iterators:
begin Return iterator to beginning
end Return iterator to end
rbegin Return reverse iterator to reverse beginning
rend Return reverse iterator to reverse end
cbegin Return const_iterator to beginning
cend Return const_iterator to end
crbegin Return const_reverse_iterator to reverse beginning
crend Return const_reverse_iterator to reverse end
Capacity:
empty Test whether container is empty
size Return container size
max_size Return maximum size
Element access:
operator[] Access elementat Access element
Modifiers:
insert Insert elements
erase Erase elements
swap Swap content
clear Clear content
emplac Construct and insert elementemplace_hint Construct and insert element with hint
Observers:
key_comp Return key comparison objectvalue_comp Return value comparison object
Operations:
find Get iterator to elementcount Count elements with a specific key
lower_bound Return iterator to lower boundupper_bound Return iterator to upper bound
equal_range Get range of equal elementsReturns an iterator that addresses thelocation succeeding the last element in a map.
Template Class public Member Functions
P.A._IG Ch - 116M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include <set>using namespace std;
void main() {
set<string> Heros;
set<string>::iterator H;
set<int> Nbre;
set<int>::iterator it;
Heros.insert("Tintin");
Heros.insert("Asterix");
Heros.insert("Obelix");
Heros.insert("Asterix");
Heros.insert("Titeuf");
Heros.insert("Obelix");
for (H= Heros.begin(); H != Heros.end(); H++)
cout<< *H << endl;
Nbre.insert(9); Nbre.insert(3); Nbre.insert(6);
for (it= Nbre.begin(); it != Nbre.end(); it++)
cout<< *it << endl;
}
Le tableau associatif Set
Affichage :
AsterixObelixTintinTiteuf369
STL
59
P.A._IG Ch - 117M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include <set>using namespace std;
void main() {
multiset<string> Heros;
multiset<string>::iterator H;
set<int> Nbre;
set<int>::iterator it;
Heros.insert("Tintin");
Heros.insert("Asterix");
Heros.insert("Obelix");
Heros.insert("Asterix");
Heros.insert("Titeuf");
Heros.insert("Obelix");
for (H= Heros.begin(); H != Heros.end(); H++)
cout<< *H << endl;
Nbre.insert(9); Nbre.insert(3); Nbre.insert(6);
for (it= Nbre.begin(); it != Nbre.end(); it++)
cout<< *it << endl;
}
Le tableau associatif MultiSet
Affichage :
AsterixAsterixObelixObelixTintinTiteuf369
STL
P.A._IG Ch - 118M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include <set>
using namespace std;
void main() {
multiset<string> Heros;
multiset<string>::iterator H;
setlocale(LC_ALL,"");
Heros.insert("Tintin");
Heros.insert("Asterix");
Heros.insert("Obelix");
Heros.insert("Asterix");
Heros.insert("Titeuf");
Heros.insert("Obelix");
for (H= Heros.begin(); H != Heros.end(); H++)
cout<< *H << endl;
if (Heros.find("Obelix") != Heros.end())
cout << "Obelix est là" << endl;
cout << "Nombre de ‘Asterix’ : " << Heros.count("Asterix") << endl;
cout << "Nombre de ‘Titeuf’ : " << Heros.count("Titeuf") << endl;
Heros.clear();
if (Heros.empty()) cout << "L’ensemble est vidé" << endl;
else cout << "MultiMap n'est pas vide" << endl;
}
Le tableau associatif MultiSet
Affichage :
AsterixAsterixObelixObelixTintinTiteuf
Obelix est là
Nombre de 'Asterix' : 2Nombre de 'Titeuf' : 1
L'ensemble est vidé
STL
60
P.A._IG Ch - 119M. BENJELLOUN : 2020-21
Dans une map, les objets stockés sont des ‘pair’. Pour chaque paire, l'attribut first correspond à la clé alors que second est la valeur.
Le tableau associatif Map
#include <iostream>
#include <string>
#include <map>
using namespace std;
void main() {
map<string, float> poids; // table qui associe le nom d'un animal à son poids
map<string, float>::iterator it;
//On ajoute les poids de quelques animaux
poids["souris"] = 0.05;
poids["tigre"] = 200;
poids["chat"] = 3;
poids["elephant"] = 10000;
for(it=poids.begin(); it!=poids.end(); it++) {
cout << it->first << " pese " << it->second << " kg." << endl;
}
system("pause");
}
Affichage :
chat pese 3 kg.elephant pese 10000 kg.souris pese 0.05 kg.tigre pese 200 kg.
STL
P.A._IG Ch - 120M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include <map>using namespace std;
template <class A> void Affichage(A Tab, string S) {
A::iterator it;
cout << S << " dans Affichage :" << endl;
for(it=Tab.begin(); it!=Tab.end(); it++)
cout<< S<<"[" << it->first << "]=" << it->second<< " et \n"; // ou (*it)->first
}
void main() {
map<string,int> nombres; // Pour chaque clé correspondra
// une seule valeur associée.
nombres["Tintin"] = 2;
nombres.insert(make_pair("Asterix",5));
nombres.insert(make_pair("Obelix",9));
nombres.insert(make_pair("Obelix",9));
nombres.insert(make_pair("Obelix",7));
Affichage(nombres, "nombres");
cout<< "Affichage hors boucle : " << endl;
cout<< "nombres[Obelix] : " << nombres["Obelix"] << " et \n";
cout<< "nombres[Tintin] : " << nombres["Tintin"] << endl;
}
Affichage :
nombre dans Affichage :
nombres[Asterix]=5 et
nombres[Obelix]=9 et
nombres[Tintin]=2 et
Affichage hors boucle :
nombres[Obelix] : 9 et
nombres[Tintin] : 2
Le tableau associatif Map
STL
61
P.A._IG Ch - 121M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include <map>
using namespace std;
template <class A> void Affichage(A Tab, string S) {
A::iterator it;
cout << S << " dans Affichage :" << endl;
for(it=Tab.begin(); it!=Tab.end(); it++)
cout<< S<<"[" << it->first << "]=" << it->second<< " et \n"; // ou (*it)->first
}
void main() {
map<string,int> nombres; // Pour chaque clé correspondra une seule valeur associée.
nombres["Tintin"] = 2;
nombres.insert(make_pair("Asterix",5));
nombres.insert(make_pair("Obelix",9));
nombres.insert(make_pair("Obelix",9));
nombres.insert(make_pair("Obelix",7));
Affichage(nombres, "nombre");
cout<< "Affichage hors boucle : " << endl;
cout<< "nombres[Obelix] : " << nombres["Obelix"] << " et \n";
cout<< "nombres[Tintin] : " << nombres["Tintin"] << endl;
}
Affichage :
Le tableau associatif Map
nombres["Obelix"] = 1;
STL
P.A._IG Ch - 122M. BENJELLOUN : 2020-21
#include <iostream>
#include <string>
#include <map>
using namespace std;
template <class A> void Affichage(A Tab, string S) {
A::iterator it;
cout << S << " dans Affichage :" << endl;
for(it=Tab.begin(); it!=Tab.end(); it++)
cout<< S<<"[" << it->first << "]=" << it->second<< " et \n"; // ou (*it)->first
}
void main() {
multimap<string,int> nombres; // Pour chaque clé correspondra une seule valeur associée.
nombres["Tintin"] = 2;
nombres.insert(make_pair("Asterix",5));
nombres.insert(make_pair("Obelix",9));
nombres.insert(make_pair("Obelix",9));
nombres.insert(make_pair("Obelix",7));
Affichage(nombres, "nombre");
cout<< "Affichage hors boucle : " << endl;
cout<< "nombres[Obelix] : " << nombres["Obelix"] << " et \n";
cout<< "nombres[Tintin] : " << nombres["Tintin"] << endl;
}
Le tableau associatif MutiMap
nombres["Obelix"] = 1;
// error C2676: '[' binaire : 'std::multimap<_Kty,_Ty>' ne définit pas cet opérateur
STL
62
P.A._IG Ch - 123M. BENJELLOUN : 2020-21
#include ...
template <class A> void Affichage(A Tab, string S) {
. . .}
void main() {
map <string,string> GSM;
map <string,string>:: iterator G;
GSM.insert(make_pair("Asterix","474222222"));
GSM.insert(make_pair("Obelix","475333333"));
GSM["Tintin"] = "476444444";
Affichage(GSM, "GSM");
G = GSM.find("Obelix"); //renvoie end si n’exite pas
if(G == GSM.end())
cout << "Obelix n'existe pas !!" << endl;
else
GSM.erase(G);
cout<< "\n GSM[i] apres suppression? : " << endl;
Affichage(GSM, "GSM");
}
Affichage :
GSM dans Affichage :GSM[Asterix]=474222222 et GSM[Obelix]=475333333 et GSM[Tintin]=476444444 et
GSM[i] apres suppression? :GSM dans Affichage :GSM[Asterix]=474222222 et GSM[Tintin]=476444444 et
Le tableau associatif Map
STL
P.A._IG Ch - 124M. BENJELLOUN : 2020-21
Le tableau associatif Map
map<char, int> map1, map2;
map < K, V >
map1.insert ( pair<char,int>('a',100) );map1.insert ( pair<char,int>('z',200) );map1.insert ( make_pair('c',500) );map1.insert ( make_pair('b',300) );map1.insert ( make_pair('W',444) );
map1 ==>:W => 444a => 100b => 300c => 500z => 200
map2.insert(map1.begin(),map1.find('c'));map2 ==>:W => 444a => 100b => 300
63
P.A._IG Ch - 125M. BENJELLOUN : 2020-21
Le tableau associatif Map
map<char, int> map1, map2; map<char, int> :: iterator M;
map < K, V >
map1.insert ( pair<char,int>('a',100) );map1.insert ( pair<char,int>('z',200) );map1.insert ( make_pair('c',500) );map1.insert ( make_pair('b',300) );map1.insert ( make_pair('W',444) );
map1 ==>:W => 444a => 100b => 300c => 500z => 200
M = map1.find(‘b’); //renvoie end si n’exite pas
if(M == map1.end())cout << " le char b n'existe pas !!" << endl;
elsemap1.erase(G);
map1 ==>:W => 444a => 100c => 500z => 200
P.A._IG Ch - 126M. BENJELLOUN : 2020-21
Le tableau associatif Map
map<string, int> M ;
map < K, V >
M["Tintin"] = 2;M.insert(make_pair("Asterix",5));M.insert(make_pair("Obelix",9));M.insert(make_pair("Obelix",9));M.insert(make_pair("Obelix",7));
Affichage :
M[Asterix] = 5 et
M[Obelix] = 9 et
M[Tintin] = 2 et
64
P.A._IG Ch - 127M. BENJELLOUN : 2020-21
Le tableau associatif Map
multimap<string, int> M ;
multimap < K, V >
M["Tintin"] = 2;M.insert(make_pair("Asterix",5));M.insert(make_pair("Obelix",9));M.insert(make_pair("Obelix",9));M.insert(make_pair("Obelix",7));
Affichage :
M[Asterix] = 5 et
M[Obelix] = 9 et
M[Obelix] = 9 et
M[Obelix] = 7 et
P.A._IG Ch - 128M. BENJELLOUN : 2020-21
#include ...
struct Etud {int id;string name;
};
void main() {
map<int, Etud> Stud;map<int, Etud>::iterator it;
Stud[124].id = 1;Stud[124].name = " Obelix";
Stud[12].id = 5;Stud[12].name = " Asterix";
Stud[120].id = 7;Stud[120].name = " Tintin";
Stud[12].id = 9;Stud[12].name = " Ass_TRix"; // écrase ancien Stud[12]
for(it=Stud.begin(); it!=Stud.end(); it++ ) cout<< it->first << " " << it->second.id << " " << it->second.name << endl;
system("pause");}
Le tableau associatif Map
Affichage :
124 1 Obelix
12 5 Asterix
120 7 Tintin
12 9 Ass_TRix
65
P.A._IG Ch - 129M. BENJELLOUN : 2020-21
#include ...
struct Etud {int id;string name;
};
void main() {
multimap<int, Etud> Stud;multimap<int, Etud>::iterator it;int static K = 1 ;
for (int i = 0; i < 4; i++) {Etud E;E.id = i + 1 ; // id = 1E.name = "Stud" + to_string ( K ); // Stud1Stud.insert(make_pair( i , E ) ); // 0 1 Stud1K++ ;
}
for(it=Stud.begin(); it!=Stud.end(); it++ ) cout<< it->first << " " << it->second.id << " " << it->second.name << endl;
system("pause");}
Le tableau associatif multiMap
Affichage :
0 1 Stud11 2 Stud22 3 Stud33 4 Stud4
P.A._IG Ch - 130M. BENJELLOUN : 2020-21
#include ...
struct Etud {int id;string name;
};
void main() {
multimap<int, Etud> Stud;multimap<int, Etud>::iterator it;int static K = 1 ;
for (int j = 0; j < 3; j++) {for (int i = 0; i < 4; i++) {
Etud E;E.id = i + 1 ; // id = 1E.name = "Stud" + to_string ( K ); // Stud1Stud.insert(make_pair( i , E ) ); // 0 1 Stud1K++ ;
}}
for(it=Stud.begin(); it!=Stud.end(); it++ ) cout<< it->first << " " << it->second.id << " " << it->second.name << endl;
system("pause");}
Le tableau associatif multiMap
Affichage :
0 1 Stud10 1 Stud50 1 Stud91 2 Stud21 2 Stud61 2 Stud102 3 Stud32 3 Stud72 3 Stud113 4 Stud43 4 Stud83 4 Stud12
66
P.A._IG Ch - 131M. BENJELLOUN : 2020-21
.first .second
• Affichage direct depuis la Map / MultiMap de toutes les instances de la clé ‘Key2’ :
– .first fournit la "lower bound"
– .second la "upper bound"
equal_range(clé)
Le tableau associatif multiMap
P.A._IG Ch - 132M. BENJELLOUN : 2020-21
#include ...
struct Etud {int id;string name;
};
void main() {
multimap<int, Etud> Stud;
int Key = 1;
if (Stud.count(Key) == 0)
cout << "Cette clé n'est pas dans la base de données \n" << endl;
else {
for (it = Stud.equal_range(Key).first; it != Stud.equal_range(Key).second; it++)
cout<< it->first << " " << it->second.id << " " << it->second.name << endl;
Le tableau associatif multiMap
Stud :
Key Stud
0 1 Stud10 1 Stud50 1 Stud91 2 Stud21 2 Stud61 2 Stud102 3 Stud32 3 Stud72 3 Stud113 4 Stud43 4 Stud83 4 Stud12
Affichage:
1 2 Stud21 2 Stud61 2 Stud10
67
P.A._IG Ch - 133M. BENJELLOUN : 2020-21
#include ...
struct Etud {int id;string name;
};
void main() {
multimap<int, Etud> Stud;
int Key = 1;
if (Stud.count(Key) == 0)
cout << "Cette clé n'est pas dans la base de données \n" << endl;
else {
for (it = Stud.equal_range(Key).first; it != Stud.equal_range(Key+1).second; it++)
cout<< it->first << " " << it->second.id << " " << it->second.name << endl;
Le tableau associatif multiMap
Affichage:
1 2 Stud21 2 Stud61 2 Stud102 3 Stud32 3 Stud72 3 Stud11
Stud :
Key Stud
0 1 Stud10 1 Stud50 1 Stud91 2 Stud21 2 Stud61 2 Stud102 3 Stud32 3 Stud72 3 Stud113 4 Stud43 4 Stud83 4 Stud12
P.A._IG Ch - 134M. BENJELLOUN : 2020-21 STL