170
++- 1 M. BENJELLOUN : 2005-06 Info II Mohammed BENJELLOUN Service d’Informatique Faculté Polytechnique de Mons [email protected]. be 2005-2006 Programmation en

Mohammed BENJELLOUN Service d’Informatique Faculté Polytechnique de Mons

  • Upload
    clovis

  • View
    33

  • Download
    5

Embed Size (px)

DESCRIPTION

Programmation en. Mohammed BENJELLOUN Service d’Informatique Faculté Polytechnique de Mons Mohammed . Benjelloun @fpms.ac.be 2005-2006. Qu'est-ce qu'un bon programme?. Il doit résoudre le PROBLEME !. Efficacité  Rapidité?. DUREE DE VIE ?. INSTANTANE !. Lisible Structuré. Portabilité. - PowerPoint PPT Presentation

Citation preview

Présentation PowerPoint C++ 2dMohammed BENJELLOUN
Qu'est-ce qu'un bon programme?
DUREE DE VIE ?
Les autres types seront dérivés de ceux-ci.
Types de base en C++
sizeof(i); retourne la taille en octet de la variable i
booléen : bool qui s'accompagne des mots-clés true et false.
Type
Représentation
Signification
Intervalle
Un caractère unique
1
entiers
signed int ou int unsigned int short ou long
entier signé (par défaut) entier positif spécifie la taille de l'emplacement mémoire utilisé
-231 à 231 –1 0 à 232 -215 à 215 –1
2 ou 4
réels
Réel simple précision Réel double précision Réel précision étendue
+-10 E-37 à +-10 E+38 +-10 E-307 à +-10 E+308
4 8
++- *
void main(void)
instruction1 ;
instruction2 ;
Tout programme doit avoir un point d’entrée nommé main()
main() est la fonction appelée lors de l’exécution du programme.
{ et } délimitent le corps de la fonction, bloc, la succession d'actions à réaliser.
Chaque expression (instruction) doit finir par ;
Commentaire : texte encadré par les symboles ‘/*’ et ‘*/’ ou une ligne
commençant par le symbole ‘//’
Pour commencer
void main(void): La fonction main ne prend aucun paramètre et ne retourne pas de valeur.
int main(void): La fonction main retourne une valeur entière à l'aide de l'instruction return (0 si pas d’erreur).
main(void) main()
Variables : déclarations,
i=9;
c1= 'A';
Identificateurs
Le C++ distingue les minuscules des majuscules.
Exemple: abc, Abc, ABC
Identificateurs valides :
Identificateurs invalides :
no-commande caractère non autorisé (-)
352.unknown
M. BENJELLOUN : 2005-06 Info II
Un identificateur ne peut pas être un mot réservé du langage :
Les mots réservés du langage C++ doivent être écrits en minuscules.
asm
auto
bool
break
case
catch
char
class
const
continue
default
delete
do
double
else
enum
extern
float
for
friend
goto
if
inline
int
long
mutable
namespace
new
operator
private
protected
public
register
return
short
signed
sizeof
static
struct
switch
template
this
typedef
union
unsigned
using
virtual
void
volatile
while
Les entrées /sorties : cin et cout
 
cout, le flux standard de sortie, habituellement associé à l'écran,
Syntaxe : cout << expression << expression << expression … ;
cin, le flux standard d’entrée, habituellement associé au clavier,
Syntaxe : cin >> valeur >> valeur >> valeur … ;
cin et cout sont définies dans la librairie <iostream.h>.
#include <iostream.h>
void main(void) {
cout << " oui tous " ;
:
#include <iostream.h>
void main () {
cin >> n ;
cin >> x ;
cin >> C ;
}
 
int n=2;
float x= 3.4;
char C= 'A' ;
cin >> n >> x >> C;
cout << C << ' ' << x << ' ' << n
V 9.9 5
M. BENJELLOUN : 2005-06 Info II
Les variables doivent être déclarées avant leur utilisation dans un début de bloc (juste après{),
zone des déclarations:
est équivalent à
'A' 's' '2' '['
++- *
Les opérateurs arithmétiques
+ addition
- soustraction
* multiplication
/ division
% ne peut être utilisé qu'avec des entiers
7.0/2
7/2.0
7.0/2.0
< plus petit
== égal
!= différent
Le résultat d'une expression logique est un booléen. Il vaut true si elle est vraie et false sinon.
!
Les structures de contrôle
Choix Multiple: switch-case
  Les décisions - if else
int i = 1;
cout <<" alors!! \n";
alors!!
}
int i = -1;
}
alors!!
}
Condition
vraie
#include <iostream.h>
void main()
cout << "i = " << i << endl;
cout << "i = " << i << endl;
{
 
tant que (expression vraie)
............;
............;
}
 
Le test se fait d'abord, le bloc d'instructions n'est pas forcément exécuté.
Syntaxe:
(Boucles)
oui
non
do
int j = 5;
M. BENJELLOUN : 2005-06 Info II
switch = AU CAS OU ... FAIRE ...
{
.......;
 
........;
........; d'instructions, pas de "break" ici.*/
}
 
++- *
char choix;
cout << "POUR SORTIR : TAPEZ 3 " << endl;
cout << " \n\t\t VOTRE CHOIX: " << endl;
 
break;
break;
break;
}
int choix;
Tableaux et Strings
Un tableau est une collection de variables de même type, appelées éléments
Type Nom_Tableau[dim];
int tab[4]; déclare un tableau de 4 valeurs entières
const int SIZE = 5;
int A[SIZE] // A est un vecteur de 5 entiers
float B[5]
int premier[] = { 1, 2, 3, 5, 7, 11, 13 };
char Tab_Char[4] = { 'A', 'C', 'F', 'G' };
int Tab[50] = { 0 };
M. BENJELLOUN : 2005-06 Info II
Chaînes de caractères ou String
En C++, il y a deux façons pour traiter et manipuler une chaîne de caractères:
char Ident[dim];
Initialisation
Pour terminer la chaîne, on place en fin de chaîne le caractère nul '\0', de code ASCII 0.
Ce caractère est soit ajouté automatiquement par le compilateur, soit introduit par le programmeur, selon les fonctions utilisées.
char S[] = {'H','e','l','l','o','\0'};
char S[6] = "Hello";
char S[] = "Le main";
Un tableau de char à une dimension : char Ident[dim];
Un type spécial string : string Ident; // Il faut inclure <string.h>
'L'
'e'
Pourquoi utiliser string Ident; plutôt que char Ident[dim]; ?
char S1[6] = "Salut", S2[6] = "Hello", S3[12];
S1= S2; S1= "Hooo"; S3=S1+S2; if(S1= =S2) …
Interdit
S1= S2; S1= "Hooo"; S3=S1+S2; if(S1= =S2) …
Autorisé
Fonctions en C++
#include …
#include <iostream>
int i, j=5, k; // définition des variables locales
i = 0 ;
j=fonc1(i) ;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
….. ;
}
Les tableaux peuvent être passés comme paramètres d'une fonction.
Ils ne peuvent pas être retournés comme résultat d'une fonction.
La longueur du tableau ne doit pas être définie à la déclaration de la fonction.
!
Modif(p);
}
#include …
var = 5
var = 500
var = 5
var = 500
M. BENJELLOUN : 2005-06 Info II
#include <iostream> … void affiche (int a, int b) { cout<<"\t i = " << a << " j = " << b << endl; }
void echange (int, int); void main () { int i= 5, j=8; affiche (i, j); echange (i, j); affiche (i, j); } void echange (int a, int b) { int tmp; tmp = b; b = a; a = tmp; }
void echange (int*, int*); void main () { int i= 5, j=8; affiche (i, j); echange (&i, &j); affiche (i, j); } void echange (int *a, int *b) { int tmp; tmp = *b; *b = *a; *a = tmp; }
void echange (int&, int&); void main () { int i= 5, j=8; affiche (i, j); echange (i, j); affiche (i, j); } void echange (int &a, int &b) { int tmp; tmp = b; b = a; a = tmp; }
i = 5 j = 8 i = 5 j = 8
i = 5 j = 8 i = 8 j = 5
i = 5 j = 8 i = 8 j = 5
++- *
#include …
cout << "\nglobale = " << globale ;
// locales à fonc
#include …
}
cout << un << " " << deux << " " << g << endl;
}
Tableaux réserver plus de places en mémoire que nécessaire.
Création d’un tableau de taille quelconque l'allocation dynamique
#include <iostream> …
for(int i=0; i<d; i++)
cout<< "\n T["<<i<<"] = " << T[i] << " C["<<i<<"] = " <<C[i];
cout << endl;
T= new int[N]; affiche(T, N, C);
for(i=0; i<N; i++){
T[i]=i;
}
T[0] = 0 C[0] = A
T[1] = 1 C[1] = B
T[2] = 2 C[2] = C
T[0] = -572662307 C[0] = A
T[1] = -572662307 C[1] = B
T[2] = -572662307 C[2] = C
T[0] = -572662307 C[0] = ¦
T[1] = -572662307 C[1] = ¦
T[2] = -572662307 C[2] = ¦
++- *
char *C = new char[N]; et Equiv à char *C;
C = new char [N];
*C = new char[N];
Tableau de taille quelconque
int i;
int i;
Les Structures
Une structure est un ensemble de variables (de types éventuellement différents), définissant un nouveau type sous un seul nom.
Les structures sont définies en utilisant le mot-clé struct.
struct Etudiant {
Déclarer des instances
Une fois la structure définie, les instances peuvent être déclarées. Par abus de langage, on appellera structure une instance de structure
struct Date {
Déclaration avant ‘;’
struct Etudiant{
102,
60.7,
};
Les membres sont accédés par le nom de l’instance, suivi de . , suivi du nom du membre
cout <<"nom = "<< JD.nom;
cout << " jour de naissance "<<JD. D_Nais.jour;
85.unknown
86.unknown
134.unknown
struct Etudiant{
#include …
}
Affiche(un_article);
cout << "Entrez le nom : "; cin >> plus_art[i].nom;
cout << "\nEntrez le prix "; cin >> plus_art[i].prix;
Affiche(plus_art[i]);
#include …
int prix;
<< " Prix = " << AR.prix;
}
Entrez le nom : Television
Entrez le prix : 300
Nom = Television Prix = 300
Une structure peut être passée, comme une autre variable, par valeur ou par adresse
Passer par valeur n’est pas toujours efficace (recopiage à l’entrée)
Passer par adresse ne nécessite pas de recopiage
++- *
#include …
}
Saisie(T1[i]);
return AA;
++- *
Sexe
Nom
adresse
Sexe
res1
res2
M
10
15
F
10
20
Pour manipuler un fichier en C++ il faut #include <fstream.h>
On y trouve essentiellement les classes:
ofstream (output file stream) permet d’écrire les données dans le fichier ;
ifstream (input file stream) permet de lire les données du fichier ;
Ouverture et fermeture d’un fichier :
ofstream output;
Écriture :
Lecture :
++- *
#include <fstream.h>
void main() {
ofstream Ecri;
Ecri << Tab1[i] << " "
<< Tab2[i]<<endl;
int Tab2[5], i=0;
Lec.open("Mon_fichier.txt");
cout << Tab1[i] << " ; " << Tab2[i]<< endl;
i++;
Ecri.open("Mon_fichier.txt");
Ecri << "Mes Donnees" << endl;
Ecri << Tab1[i] << " "
<< Tab2[i]<<endl;
cout<<"Erreur"<<endl;
N
Nmax
+ 6
6
-7
N--
1
3
5
7
8
9
{
else fin = m;
else return 0;
const int NMax = 5;
{

void saisie(struct Element T[], int &n, int &NM)
{
T[i].nom = name;
++- *
struct point
struct point Sgm[7];
// Sgm[3].y est le champ y de la 4è position : 4
Avantages : Facilité de création et de manipulation (accès à un élément, …)
Inconvénients : place mémoire, difficilement extensible, insertion n’est
possible que par décalage de tous les éléments suivants.
struct point Sgm[7]; ou
struct Date *Sgm; avec new
Sgm[0]
Sgm[1]
Sgm[2]
1 1
5 2
9 3
13 4
17 5
21 6
25 7
Listes Chaînées
JJ
++- *
M. BENJELLOUN : 2005-06 Info II
Une liste chaînée (linked list) est composée de nœuds (node), chacun ayant un pointeur vers le nœud suivant de la liste. Chaque nœud « contient » ou « est » une entité.
++- *
M. BENJELLOUN : 2005-06 Info II
Une liste simplement chaînée : une cellule est un enregistrement qui peut être déclarée comme suit:
struct Node {
};
};
++- *
M. BENJELLOUN : 2005-06 Info II
 
struct Cellule *suiv; // pointeur sur le prochain maillon
};
 
Modéliser une liste chaînée consiste à allouer dynamiquement les cellules chaque fois que cela est nécessaire.
Listes Chaînées
@4000
@4000
@0700
@0900
@4000
@4000
@0700
@0900
M. BENJELLOUN : 2005-06 Info II
Initialiser les valeurs de la structure représentant la liste pointée par Debut pour que celle-ci soit vide. Une liste est vide lorsque Tête_List (Fin_List) pointe sur Vide.
Les différentes opérations et fonctions
typedef struct Cellule{
}CEL;
debut = new (CEL);
typedef : mot réservé, crée de nouveaux noms de types de données
Ex : typedef char * STRING; fait de STRING un synonyme de "char * "  
Portée : comme les variables.
CEL * new_node(Type value)
Cette fonction réserve l'espace mémoire nécessaire pour une nouvelle Cellule dans la liste, assigne les données, et retourne un pointeur sur cette Cellule.
typedef struct Cellule{
typedef struct Cellule{
Nouvelle cellule dans une liste chaînée vide
Si
debut = new CEL;
debutname = "Denis";
debutsuiv = NULL;
Le début de la liste est indiqué par un pointeur indépendant (debut) et la fin par NULL
Denis\0
debut
NULL
prec
Claire
debut
prec
CEL *insere_en_tete(string nom , CEL *deb )
{
if (prec!=NULL) {
precname = nom; // assignation de nom
}
Insérer une nouvelle cellule après la cellule prec
debut
NULL
prec
OK?
Claire
Denis
Alfred
Que fait ce code ?
void Affichage (CEL *debut)
CEL *p;
Parcourir une liste
NULL
debut
debut est un pointeur sur la cellule qui contient le premier élément de la
liste
Claire
Denis
Alfred
p
p
p
void liberation(CEL *L){
Liberation
Si
TRI
NULL
NULL
Claire
Denis
Alfred
Claire
Denis
Alfred
1
2
3
838.unknown
NULL
TRI
Claire
Denis
Alfred
1
2
3
Alfred
1
Claire
3
Denis
NULL
2
841.unknown
Supprimer une cellule
Libérer une cellule
Rechercher une cellule
Autres fonctions
En résumé, une liste chaînée par pointeurs permet une insertion et une suppression rapide des éléments. Cependant, contrairement au tableau, une liste chaînée interdit un accès direct aux éléments (mis à part la tête et la queue).
Si l’ordre d’insertion et de suppression des éléments dans la liste
importe, deux structures de données sont particulièrement adaptées :
la pile et la file.
++- *
M. BENJELLOUN : 2005-06 Info II
Une pile est une liste qui respecte la régle “dernier arrivé, premier sorti”. C’est une structure de données pour laquelle l’ajout et la suppression d’un élément ne sont autorisés qu’à une seule extrémité, appelée sommet de la pile.
Quant on ajoute un élément, celui-ci devient le sommet de la pile. Quant on retire un élément de la pile, on retire toujours le sommet. Pour résumer, le dernier entré/premier sorti liste LIFO (Last In, First Out).
Les piles sont souvent commodes pour dé-récursiver un problème.
Modéliser une pile consiste à utiliser une liste chaînée en n'utilisant que les opérations ajouterTete et retirerTete. Dans ce cas, on s'aperçoit que le dernier élément entré est toujours le premier élément sorti.
PILE [stack, lifo]
Exemples
fonction BOOLEEN empilerElement(CEL * p, ELEMENT Nouv)
{
Empiler un élément sur une pile
Cette fonction empile l'élément Nouv au sommet de la pile pointée par p. Cela revient à ajouter l'élément Nouv en tête de la liste. VRAI est retournée si l'élément a bien été ajouté.
Nouv
Tête
Elm1
Elm2
Elm3
M. BENJELLOUN : 2005-06 Info II
 
{
}
}
Il ne faut pas oublier de libérer la mémoire à chaque retrait du sommet de la pile.
Dépiler un élément d'une pile
Tête
Elm1
Elm2
Elm3
Elm1
Elm2
Elm3
Nouv
Elm1
Elm2
Elm3
LIFO
Last-In-First-Out
Le dernier élément ajouté dans la liste, est le premier à en sortir.
Opérations:
Push(5)
5
NULL
struct NODE *pLifoStart;
pNew->nombre = nombre;
pNew->next = pLifoStart;
Simulation de la factorielle
Simulation de la factorielle
int Pop( int *pNombre ) // == supprimer début de liste
{
récupérer l'élément en tête de liste avant de le supprimer
delete pTemp;
return 1;
void CalculFact( int num)
}
dé-récursiver un problème.
M. BENJELLOUN : 2005-06 Info II
Une file d'attente est une structure de données pour laquelle l’ajout et la suppression d’un élément ne sont autorisés qu’aux seules extrémités, appelées la tête et la queue de la file. Les éléments sont ajoutés en queue de file et sont retirés en tête de file. Pour résumer, le premier entré/ le premier sorti liste FIFO (First In, First Out).
FILE D'ATTENTE , queue [queue, FiFo]
Exemple : Imprimante en réseau
Jeu de 52 cartes (4 couleurs et 13 puissances).
Le jeu est d'abord mélangé pour ensuite être coupé afin de constituer deux tas de 26 cartes
++- *
++- *
3 joueurs
4 joueurs
. . .
. . .
Listes doublement chaînées
int data; // les informations
};
debut
fin
data
prev
next
NULL
Déclaration d'une structure comportant 
• deplace pour modifier les coordonnées d'un point ;
• affiche pour afficher un point .
Voici comment nous pourrions déclarer notre structure point :
Supposons que nous souhaitions associer à la structure trois fonctions :
struct point
int y ;
void initialise (int, int) ;
void deplace (int, int) ;
// Définition des fonctions membres du type point
#include <iostream>
{
{
}
opérateur de "résolution de portée"
++- *
void main()
a.initialise (5, 2) ; a.affiche () ;
a.deplace (-2, 4) ; a.affiche () ;
void point::affiche ()
}
struct point
struct point Segm[7];
// Segm[3].y est le champ y de la 4è position : 4
Avantages : Facilité de création et de manipulation (accès à un élément, …)
Inconvénients : place mémoire, difficilement extensible, insertion n’est
possible que par décalage de tous les éléments suivants.
struct point Segm[7]; ou
struct Date *Segm; avec new
1 1
5 2
9 3
13 4
17 5
21 6
25 7
struct Personne {
int id;
string nom;
void saisie();
void affiche();
Objet et classe
Le fondement de la programmation orientée objet (POO) est de pouvoir protéger certaines données d’une structure, d’où la nécessité des classes.
La notion de classe donne en fait la Définition d'un objet.
++- *
struct Client
l'extérieur de la classe
La déclaration d'une classe est voisine de celle d'une structure. Il suffit de:
• remplacer le mot clé struct par le mot clé class,
• préciser quels sont les membres publics (fonctions ou données) et les membres privés en utilisant les mots clés public et private.
Définition d'une classe
Encapsulation des données
Les divers champs d'une structure sont accessibles en n'importe quel endroit du programme. Une opération telle que celle-ci est donc faisable :
clientele[0].Solde = 25000;
Le solde d'un client peut donc être modifié sans passer par une méthode dont ce serait le but.
struct Client
Encapsulation
L'encapsulation est un mécanisme consistant à rassembler les données et les méthodes au sein d'une structure en cachant l'implémentation de l'objet. Cacher l'information contenue dans un objet et de ne proposer que des méthodes de manipulation de cet objet.
Ainsi les propriétés contenues dans l'objet seront assurés/validés par les méthodes de l'objet et ne seront plus de la responsabilité de l'utilisateur extérieur.
L'utilisateur extérieur ne pourra pas modifier directement l'information et risquer de mettre en péril les propriétés comportementales de l'objet.
L'encapsulation permet donc de garantir l'intégrité des données contenues dans l'objet.
(masquage des données)
Que signifient public, private et protected ?
Un membre déclaré public dans une classe peut être accédé par toutes les autres classes et fonctions.
Un membre déclaré private dans une classe ne peut être accédé que par les autres membres de cette même classe.
++- *
M. BENJELLOUN : 2005-06 Info II
Un membre public d'une classe peut être accédé partout où il est visible ; un membre privé ne peut être accédé que depuis une fonction membre de la classe .
class point
int x ;
int y ;
void initialise (int, int) ;
void deplace (int, int) ;
{
Un objet
Un objet est donc 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 Liste
Liste *debut=NULL;
void main()
// on peut accéder aux "membre public" avec .
a.initialise (5, 2) ; a.affiche () ;
a.deplace (-2, 4) ; a.affiche () ;
++- *
M. BENJELLOUN : 2005-06 Info II
Les mots clés public et private peuvent apparaître à plusieurs reprises dans la définition d'une classe, comme dans cet exemple :
class X
...
} ;
Si l'on rend publics tous les membres d'une classe, on obtient l'équivalent d'une structure. Ainsi, ces deux déclarations définissent le même type point :
struct point class point
class vecteur {
return r;
class point
{
x = abs ; y = ord ;
#include <iostream>
};
++- *
M. BENJELLOUN : 2005-06 Info II
Un constructeur est une fonction membre d’initialisation (définie comme les autres fonctions membres) qui sera exécutée automatiquement à chaque création d'un objet.
Le constructeur :
définit l'initialisation d'une instance,
appelé implicitement à toute création d'instance,
ne peut retourner aucune valeur, (fonction membre non typée même pas void ),
peut admettre des arguments qui sont en fait les valeurs d’initialisation
des différents champs de la variable.
Constructeur et destructeur
Il peut y avoir autant de constructeurs que l’on veut (tant qu’ils diffèrent par leur nombre et types d’arguments), ce qui est très intéressant pour initialiser les variables avec différents types; mais il n’y a qu’un seul destructeur par classe !
class point
point (int, int) ; // constructeur
point (float, float) ; // constructeur
De même,
le destructeur est une fonction membre appelée automatiquement au moment de la destruction de l'objet, il :
porte le nom de sa classe précédé d'un tilde (~),
n'a pas de type de retour (même pas void),
définit la "désinitialisation" d'une instance,
appelé implicitement à toute disparition d'instance,
fonction membre non typée et sans paramètre.
mais il n’y a qu’un seul destructeur par classe !
class point
point () ; // constructeur
Constructeurs par défaut
}
}
Par définition, le constructeur par défaut est : A::A(); // Avec aucun paramètre !
Rôle : il crée une instance non initialisée quand aucun autre constructeur fourni n’est applicable.
class Liste
Liste *debut=NULL;
class Pile {
int size; // nombre d’élément dans la pile
public:
M. BENJELLOUN : 2005-06 Info II
Comment concevoir le type de classe CLAS de façon que ce programme :
void main() {
CLAS x;
Constructeurs par paramètres
{
nom = info ;
Suiv = suiv ;
Long = Lo;
Larg = La;
class point
point () ; // constructeur
point a ;
à partir du moment où un constructeur est défini, il doit pouvoir être appelé (automatiquement) lors de la création de l'objet a. Ici (Ex2), le constructeur a besoin de deux arguments.
Ceux-ci doivent obligatoirement être fournis dans notre déclaration, par exemple :
point a(2,5) ;
point (int, int) ; // constructeur
~ point (); //prototype du destructeur
class x {
int i,j ;
...
++- *
#include <iostream>
Long = Lo;
Larg = La;
}
};
#include <iostream>
Long = Lo;
Larg = La;
}
};
private:
Erreur
++- *
M. BENJELLOUN : 2005-06 Info II
Initialisation, affectation d’un objet par un autre de la même classe
#include <iostream>
Long = Lo;
Larg = La;
}
};
Rc1=CRec(5,15);
CRec Rc3=Rc1; // initialisation
cout << "\n Surface rectangle 3 = " << Rc3.CalcSurf();
cout << "\n Surface rectangle 4 = " << Rc4.CalcSurf();
}
Surface rectangle 1 = 75
Surface rectangle 3 = 75
Surface rectangle 4 = 75
Constructeurs par défaut et par paramètres
Un constructeur par défaut et par paramètres :
Constructeur possédant des paramètres avec des valeurs de défaut.
class CRec
Long = Lo;
Larg = La;
++- *
#include <iostream>
{ x = abs ; y = ord ;
}
}
} ;
void main()
point c(3,3) ;
int i ;
point b(i,2*i) ; // objets créés dans un bloc
}
****** Debut main *****
** Boucle tour numero 1
** Boucle tour numero 2
** Boucle tour numero 3
****** Fin main ******
?
++- *
void main()
point b(i,2*i) ; // objets créés dans un bloc
}
point b(1,2) ; // objets créés dans un bloc
cout << "** Boucle tour numero " << 2 << "\n" ;
point b(2,4) ; // objets créés dans un bloc
cout << "** Boucle tour numero " << 3 << "\n" ;
point b(3,6) ; // objets créés dans un bloc
cout << "****** Fin main ******\n" ;
#include <iostream>
{ num = n ;
}
}
}
fct(i) ;
++- *
#include <iostream>
{ x = abs ; y = ord ;
}
}
} ;
a = point (1, 2) ; // un objet temporaire
a = point (3, 5) ; // un autre objet temporaire
cout << "****** Fin main ******\n" ;
void main()
// point * C;
a.initialise (5, 2) ; a.affiche () ;
a.deplace (-2, 4) ; a.affiche () ;
Objet dynamique
par appel d’un constructeur à 2 arguments.
(*C).affiche(); ou
Caffiche();
delete C;
#include <iostream>
public :
{ x=abs ; y=ord ;
cout << "++ Appel Constructeur \n" ;
{ cout << "-- Appel Destructeur \n" ;
void main()
{ point * adr ;
fct (adr) ;
cout << "** Fin fct \n" ;
#include <iostream>
public :
demo (int abs=1, int ord=0) // constructeur I (0, 1 ou 2 arguments)
{ x = abs ; y = ord ;
}
~demo () ; // destructeur
{ cout << "constructeur II (recopie) : " << d.x << " " << d.y << "\n" ;
x = d.x ; y = d.y ;
}
{ cout << "entrée fct\n" ;
fct (a, adr) ;
}
Quels sont les résultats fournis par l’exécution de ce programme?
++- *
#include <iostream>
public :
demo (int abs=1, int ord=0) // constructeur I (0, 1 ou 2 arguments)
{ x = abs ; y = ord ;
}
~demo () ; // destructeur
{ cout << "constructeur II (recopie) : " << d.x << " " << d.y << "\n" ;
x = d.x ; y = d.y ;
}
{ cout << "entree fct\n" ;
fct (a, adr) ;
constructeur I : 3 3
entree fct
Synthèse
....
};
=> l'argument n'est jamais modifié
=> l'argument peut être modifié
Passage par const référence
=> l'argument n'est jamais modifié
#include <iostream>
point (int) ; // constructeur 2 (un argument)
point (int, int) ; // constructeur 3 (deux arguments)
void affiche () ; // fonction affiche 1 (sans arguments)
void affiche (char []) ; // fonction affiche 2 (un argument chaîne)
} ;
{ x = y = abs ;
{ x = abs ; y = ord ;
{ cout << "Je suis en : " << x << " " << y << "\n" ;
}
{ cout << message ;
point b (5) ; // appel constructeur 2
b.affiche ("Point b - ") ; // appel fonction affiche 2
point c (3, 12) ; // appel constructeur 3
c.affiche ("Hello ---- ") ; // appel fonction affiche 2
}
Point b - Je suis en : 5 5
Hello ---- Je suis en : 3 12
Une fonction membre peut
#include <iostream>
using namespace std ;
hasard::hasard (int max) // constructeur : il tire 10 valeurs au hasard
// rappel : rand fournit un entier entre 0 et RAND_MAX
{ int i ;
}
{ int i ;
cout << "\n" ;
}
Le rôle du constructeur ne se limite pas toujours à une initialisation de l'objet. Le travail réalisé par le constructeur peut être beaucoup plus élaboré.
Voici un programme exploitant une classe nommée hasard, dans laquelle le constructeur fabrique dix valeurs entières aléatoires qu'il range dans le membre donnée val (ces valeurs sont comprises entre zéro et la valeur qui lui est fournie en argument) :
void main()
++- *
#include <iostream>
using namespace std ;
int * val ; // pointeur sur les valeurs
public :
{ int i ;
val = new int [nbval = nb] ;
}
{ int i ;
cout << "\n" ;
hasard suite1 (10, 5) ; // 10 valeurs entre 0 et 5
suite1.affiche () ;
hasard suite2 (6, 12) ; // 6 valeurs entre 0 et 12
suite2.affiche () ;
0 2 0 4 2 2 1 4 4 3
2 10 8 6 3 0
Dans le constructeur, l'instruction :
val = new [nbval = nb] ;
nbval = nb ;
Le pointeur spécial d’instance : this
Le mot this est un mot réservé contenant l’adresse de l’objet courant.
Ce pointeur sert, entre autres, à retourner une référence à cet objet pour les appels en cascade.
Dans certaines conditions particulières, il est nécessaire de disposer d’un moyen de désigner depuis une fonction membre, non pas les données membres, mais l’instance elle-même de la classe sur laquelle la méthode membre est appelée.
++- *
#include <iostream>
{ x = abs ; y = ord ;
<< " a l'adresse : " << this << "\n" ;
<< " a l'adresse : " << this << "\n" ;
a = point (1, 2) ; // un objet temporaire
a = point (3, 5) ; // un autre objet temporaire
cout << "****** Fin main ******\n" ;
****** Fin main ******
++- *
#include <iostream>
point (int abs=0, int ord=0) // Un constructeur ("inline")
{ x=abs; y=ord ; }
} ;
}
{ point a(5), b(3,15) ;
++- *
Les tableaux d’objets
point () ; // constructeur
delete [] Dcourbe;
La déclaration de ce tableau convient-elle ?
point Tab[3] ;
point (int, int) ; // constructeur
~ point (); //prototype du destructeur
Une des solutions : ??????
#include <iostream>
{ x=abs ; y =ord ;
}
}
} ;
cout << "*** fin programme ***\n" ;
#include <iostream>
template <class T> T min (T a, T b)
{ if (a < b) return a ; // ou return a < b ? a : b ;
else return b ;
int n=4, p=12 ;
float x=2.5, y=3.25 ;
char a='A', b='B';
cout << "min (n, p) = " << min (n, p) << "\n" ; // int min(int, int)
}
    template<class T>
    {
    }
++- *
#include <iostream>
#include <string>
T x ; T y ;
x = abs ; y = ord ;
cout << "Paire : " << x << " " << y << "\n" ;
}
point <string> as ("Salut", " A vous") ; as.affiche () ;
}
Paire : 3 5
Paire : d y
Paire : 3.5 2.3
#include <iostream>
#include <string>
friend Copain;
// Les fonctions membres de la classe Copain ont ainsi accès
// aux attributs privés de la classe Qui.
};
void moi() { cout << nom << " "; }
// si pas de friend Copain; dans Qui
// cannot access private member declared in class 'Qui'
}
};
friend
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.
L’héritage
Il est possible de représenter sous forme de hiérarchie de classes, parfois appelée arborescence de classes, la relation de parenté qui existe entre les différentes classes. L'arborescence commence par une classe générale appelée superclasse (parfois classe de base, classe parent, classe mère ou père). Puis les classes dérivées (classe fille ou sous-classe) deviennent de plus en plus spécialisées. Ainsi, on peut généralement exprimer la relation qui lie une classe fille à sa mère par la phrase "est un" .
Un omnivore est un animal mais pas forcement l’inverse
++- *
Principe de l’héritage
Les classes dérivées sont un mécanisme simple pour définir une nouvelle classe en ajoutant des facilités à une classe existante sans reprogrammer ou recompiler la classe de base.
On peut ainsi utiliser l’héritage pour les besoins de généralisation, de réutilisation.
La classe dérivée hérite des attributs et des fonctions de la classe de base.
La classe dérivée est plus spécifique que la classe en ajoutant des attributs et des fonctions membres.
En C++, il existe l’héritage simple, et l’héritage multiple. Dans ce cours, nous ne nous intéresserons qu’à l’héritage simple.
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.
Ex:class ClasseDerivee : public ClasseBase {...}
class Personne {
voiture est  une sorte de Vehicule
voiture est "dérivée de" Vehicule
voiture est un Vehicule spécialisé.
voiture est une "sous-classe" de Vehicule
Vehicule est une "classe de base" de voiture
Vehicule est la "superclasse" de voiture
Comment exprime t-on l'héritage en C++?
++- *
Mode de dérivation
Lors de la définition de la classe dérivée il est possible de spécifier le mode de dérivation par l'emploi d'un des mots-clé suivants :
    public, protected ou private.
Ce mode de dérivation détermine quels membres de la classe de base sont accessibles dans la classe dérivée.
Par défaut, le type d’héritage est privé (par défaut le mot-clé private.)
Les membres privés de la classe de base ne sont jamais accessibles par les membres des classes dérivées.
class ClasseDerivee : Mode ClasseBase {...}
class CptBanque {
void deposer(float);
void retirer(float);
float getSolde();
};
La classe CptPlus est un CptBanque avec de nouvelles fonctionnalités (un prélèvement automatique). Elle hérite des champs et méthodes de CptBanque et possède en plus un champ prelev et de la méthode prelever.
Qualifier la classe CptPlus comme héritant public de CptBanque, signifie que tous les champs et méthodes public de la classe CompteBanque (classe de base) sont définis implicitement public dans la classe ComptePrelevementAuto (classe dérivée public).
héritage simple public
C'est la forme la plus courante d'héritage
++- *
Héritage Public: Les types d’attributs
C'est la forme la plus courante d'héritage
Les attributs private, protected et public de la classe de base restent les mêmes pour la classe dérivée.
Le type d’attribut protected est
le plus utilisé lors de l’héritage.
class ClasseDerivee : public ClasseBase
Voiture X;
X.pub1(); // OK
X.pub2(); // OK
protégés (protected), c'est à dire accessibles aux membres de la classe et ses classes dérivées (par héritage);
Classe de base
M. BENJELLOUN : 2005-06 Info II
Il permet de modéliser les relations "Y est composé de un ou plusieurs X" .
Plutôt que d'hériter de façon privée de la classe de base X, on peut faire de la classe de base une donnée membre (composition).
class TXT {
cout << ObjtDim.length(); // ERREUR
Tous les attributs de la classe de base deviennent private pour la classe dérivée.
Héritage Privé: Les types d’attributs
Classe de base
M. BENJELLOUN : 2005-06 Info II
Il peut être intéressant d'avoir des données d'une classe qui soient privés en dehors d'utilisation de l'héritage mais publics dans une chaîne d'héritage. les données protégés (protected).
class TXT {
};
Les attributs public de la classe de base deviennent protégés pour la classe dérivée.
Héritage Protégé: Les types d’attributs
Classe de base
mode de  dérivation
Statut dans la  classe dérivée 
public
public
public
 protected 
protected
private
inaccessible
  protected  
public
protected
protected
protected
private
inaccessible
private
public
private
protected
private
private
inaccessible
REDEFINITION DE METHODES DANS LA CLASSE DERIVEE
Les méthodes (fonctions, …) de la classe de base peuvent être redéfinies dans la classe dérivée (le même nom que dans la classe de base). Elles demeurent accessibles via l'opérateur de résolution de portée ("::").
#include <iostream>
protected:
void f3();
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;
}
/* --- Déclaration et définition de la classe pointcol ----- */
class pointcol : public point // pointcol dérive de point
{ int couleur ;
} ;
class point
void point::initialise (int abs, int ord)
{
{
}
}
couleur = 5
++- *
class pointcol : public point // pointcol dérive de point
{ int couleur ;
} ;
{
{
}
}
Je suis en 5 10
Je suis en 20 30
Je suis en 20 30
Je suis en 20 30
Conversions automatiques : si B hérite de A, alors toutes les instances de B sont aussi des instances de A, et il est donc possible de faire :
A a; B b; a=b;
++- *
#include <iostream>
/* pour compiler la définition de pointcol) */
using namespace std ;
} ;
}
{ initialise (abs, ord) ;
p.deplace (2,4) ; p.affichec () ;
p.colore (2) ; p.affichec () ;
++- *
#include <iostream>
public :
point (int abs=0, int ord=0) // constructeur de point ("inline")
{ cout << "++ constr. point : " << abs << " " << ord << "\n" ;
x = abs ; y =ord ;
} ;
pointcol::pointcol (int abs=0, int ord=0, int cl=1)
{ cout << "++ constr. pointcol : " << abs << " " << ord << " " << cl << "\n" ;
couleur = cl ;
++- *
#include <iostream>
public :
point (int abs=0, int ord=0) // constructeur de point ("inline")
{ cout << "++ constr. point : " << abs << " " << ord << "\n" ;
x = abs ; y =ord ;
} ;
pointcol::pointcol (int abs=0, int ord=0, int cl=1) : point (abs, ord)
{ cout << "++ constr. pointcol : " << abs << " " << ord << " " << cl << "\n" ;
couleur = cl ;
++- *
héritage Constructeurs et destructeurs
public :
point (int abs=0, int ord=0) // constructeur de point ("inline")
{ cout << "++ constr. point : " << abs << " " << ord << "\n" ;
x = abs ; y =ord ;
{ cout << "-- destr. point : " << x << " " << y << "\n" ;
}
} ;
~pointcol () // destructeur de pointcol ("inline")
{ cout << "-- dest. pointcol - couleur : " << couleur << "\n" ;
}
} ;
pointcol::pointcol (int abs=0, int ord=0, int cl=1) : point (abs, ord)
{ cout << "++ constr. pointcol : " << abs << " " << ord << " " << cl << "\n" ;
couleur = cl ;
delete adr ;
++ constr. point : 2 3
++ constr. point : 12 0
++ constr. point : 12 25
-- dest. pointcol - couleur : 1
-- destr. point : 12 25
-- dest. pointcol - couleur : 1
-- destr. point : 12 0
-- dest. pointcol - couleur : 1
-- destr. point : 2 3
-- dest. pointcol - couleur : 3
-- destr. point : 10 15
// classe de base pour liste chaînée
template<class Elem> class List {
public :
template<class Elem> class CycleList : public List<Elem> {
//...
++- *
M. BENJELLOUN : 2005-06 Info II
Qu'est ce que la "STL"?
La STL ("Standard Templates Library") est une librairie qui est constituée principalement par des classes containers (Conteneurs :collections d'objets ;
très efficace), ainsi que des fonctionnalités pour parcourir (iterator) leur contenu et des algorithmes pour travailler sur leur contenu.
STL :
C++ Lists :
Container constructors
Container operators
begin
clear
empty
end
returns an iterator just past the last element of a list
erase
insert
pop_back
pop_front
push_back
push_front
remove
remove_if
splice
swap
++- *
#include <list>
#include <iostream>
listInt.push_back(33);
listInt.push_back(10);
//afficher et enlever des valeurs au debut de la liste
cout <<listInt.front() <<endl;
listInt.push_back(44);
//afficher et enlever des valeurs au debut de la liste
cout <<listInt.front() <<endl;
33
10
44
#include <vector>
#include <iostream>
vector<int> vecInt(MAX);
vecInt[i] = i+1;
cout <<vecInt[i] <<endl;
++- *
#include <string>
#include <iostream>
#include <map>
void main(){
map<string, int, less<string > > age; // age est une map de string à int
age["Fred"] = 42; // Fred a 42 ans de
age["Barney"] = 37; // Barney a 37 ans
++age["Fred"]; // incrémente l'âge de Fred.
cout << "Fred a " << age["Fred"] << " an(s)\n";
--age["Barney"];
}
++- *
void main() {
ListeMap["Mary"] = 5551212; // Le numéro de Mary a changé
// Inserser en utilisant la fonction <tt>insert</tt>: TRi croissant
ListeMap.insert( MyMap :: value_type( "Xavier", 777 ) );
ListeMap.insert( MyMap :: value_type( "Chuck", 1234567 ) );
ListeMap.insert( MyMap :: value_type( "James Bond", 007 ) );
ListeMap.insert( MyMap :: value_type( "Rob", 666 ) );
ListeMap.insert( MyMap :: value_type( "Xavier", 777 ) );
ListeMap.insert( MyMap :: value_type( "Chuck", 1234567 ) );
// Parcourir et afficher la liste
for( my_it = ListeMap.begin(); my_it != ListeMap.end(); my_it++ )
cout << (*my_it).first << " " << (*my_it).second << endl;
ListeMap.erase(ListeMap.begin(), ListeMap.end());
using namespace std;
Chuck 1234567
#include <map>
#include <iostream>
#include <string>
avion['A'] = "Alpha";
avion['E'] = "Echo";
avion['T'] = "Tango";
avion['Z'] = "Zulu";
cout <<avion['A'] <<endl;
cout <<avion['T'] <<endl;
map<char,string>::iterator it;
cout << (*it).first <<" --> " <<(*it).second <<endl ;
TAB[0]
TAB[1]
void main(){
1 : Saisie et Affichage
3 : Supprimer le début et Affichage
4 : Tri selon NOM et Affichage
5 : Tri selon Id et Affichage
6 : Quitter
void main() {
case 1: Saisie(…); Affichage(…); break;
case 2: Ajouter(…); Affichage(…); break;
case 3: Effacer(…); Affichage(…); break;
case 4: triabulle_nom(…); Affichage(…); break;
case 5: triabulle_Code(…); Affichage(…); break;
case 6: cout <<"\n\n Fin du Programme \n\n"; break;
}
struct Personne {
int id;
string nom;
void saisie();
void affiche();
cin >> id;
cin >> nom;
{
nouveau->Element.id=X.id;
nouveau->Element.nom=X.nom;
return nouveau; // retour de la nouvelle position
}