Génie Logiciel I
Cours I - Introduction au C++
Nicolas Kielbasiewicz
C.D.C.S.P./I.S.T.I.L./I.C.J.
Filière M.A.M. 2ème année - 2008/2009
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I Filière M.A.M. 2ème année - 2008/2009 1 / 33
Plan du cours
1 Introduction générale
2 C++ sans les objets
3 Objets et classes
4 Les classes comme composants logiciels
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I Filière M.A.M. 2ème année - 2008/2009 2 / 33
Problématique
Les insuffisances de la programmation fonctionnelle
La programmation fonctionnelle ou procédurale vise à découper un programme en
procédures ou algorithmes. Elle repose sur l’équation dite de Wirth :
algorithmes + structures de données = programmes
+ structuration des programmes;
+ efficacité accrue;
- extensibilité limitée;
- réutilisabilité limitée.
L’inconvénient est le découplage entre les données et les procédures.
Pour des programmes de plus en plus complexes, la productivité diminue et le coût
de développement augmente.
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I Filière M.A.M. 2ème année - 2008/2009 3 / 33
Problématique
Les apports de la programmation orientée objet
La programmation orientée objet ou P.O.O. est basée sur la notion d’objet, c’est à
dire des entités informatiques correspondant à des objets du monde réel.
L’équation de Wirth est remplacée par l’équation de la P.O.O., qui lie les
procédures aux données :
méthodes + données = objets
encapsulation : les données d’un objet ne sont pas modifiées directement,
mais par des méthodes;
classes : description d’un ensemble d’objets ayant une structure de données
commune et les mêmes méthodes;
héritage : concept lié à la notion de spécialisation. Cela permet la définition
une classe d’objets plus spécialisés qui réutilisera la classe de départ en bloc;
polymorphisme : définition d’objets génériques ou patrons.
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I Filière M.A.M. 2ème année - 2008/2009 4 / 33
Problématique
Emergence des langages objets
Langages objets purs : Simula, SmallTalk, Eiffel, Java . . .
langages à extension objet : Turbo Pascal, Flavors, Emicat . . .
Langages intermédiaires : C++, . . .
Besoins de la simulation numérique :
vitesse d’exécution
extensibilité et réutilisabilité
Le langage FORTRAN qui a dominé le monde du calcul scientifique de 1954 à
2000, n’est pas à extension objet (FORTRAN 03 ?). Dans les années 90, le choix
s’est tourné vers le C++, Java souffrant de temps de calculs prohibitifs.
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I Filière M.A.M. 2ème année - 2008/2009 5 / 33
Objectifs du cours
Génie Logiciel I : 15h C.M. (N. Kielbasiewicz) / 30h T.P. (S. Delcourte)
I Programmation Orienté Objet : C++
I Introduction aux outils de développement logiciel : U.M.L.
Génie Logiciel II : 15h C.M. (N. Kielbasiewicz) / 15h T.P. (S. Delcourte)
I Introductions aux outils de développement logiciel (suite) : U.M.L.
I Interfaces Graphiques Utilisateurs : Java
I Encapsulation de langages
Evaluation Génie Logiciel I :
Examen prévu le 1er décembre de 10h à 12h
Projet réalisé en partie en T.P.s (dernière séance le 17 décembre)
Supports de cours :
format pdf en ligne sur https://cdcsp.univ-lyon1.fr/~kielbasiewicz;
format papier en fin de cours.
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I Filière M.A.M. 2ème année - 2008/2009 6 / 33
Premier contact
L’incontournable Hello World !
Hello World
#i n c l u d e <i o s t r e a m >
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
s t d : : c o u t << ” H e l l o World ! ! ” << s t d : : e n d l ;
e x i t ( EXIT SUCCESS ) ;
}
Hello World 2
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
c o u t << ” H e l l o World ! ! ” << e n d l ;
e x i t ( EXIT SUCCESS ) ;
}
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I Filière M.A.M. 2ème année - 2008/2009 7 / 33
Prototype des fonctions
C vs. C++
En C En C++
double f ( v o i d ) ; double f ( ) ;
g ( bool , f l o a t , i n t ) ; v o i d g ( bool , f l o a t , i n t =12);
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I Filière M.A.M. 2ème année - 2008/2009 8 / 33
Entrées / sorties standard
C vs. C++
En C En C++
#i n c l u d e < s t d i o . h> #i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
p r i n t f ( ”H e l l o \n ” ) ; c o u t << ”H e l l o ”<< e n d l ;
scanf (); c i n >> i
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I Filière M.A.M. 2ème année - 2008/2009 9 / 33
Passage par valeur
Exemple de la permutation
Code source
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
v o i d permute ( i n t , i n t ) ;
i n t n =10 , p =20;
c o u t << ”a v a n t a p p e l : ” << n << ” ” << p << e n d l ;
permute ( n , p ) ;
c o u t << ” a p r e s a p p e l : ” << n << ” ” << p << e n d l ;
e x i t ( EXIT SUCCESS ) ;
}
v o i d permute ( i n t a , i n t b ) {
int c ;
c o u t << ”d e b u t p e r m u t e : ” << a << ” ” << b << e n d l ;
c=a ; a=b ; b=c ;
c o u t << ” f i n p e r m u t e : ” << a << ” ” << b << e n d l ;
}
Filière M.A.M. 2ème année - 2008/2009 10 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Passage par adresse
Exemple de la permutation
Code source
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
v o i d permute ( i n t ∗ , i n t ∗ ) ;
i n t n =10 , p =20;
c o u t << ”a v a n t a p p e l : ” << n << ” ” << p << e n d l ;
p e r m u t e (&n ,& p ) ;
c o u t << ” a p r e s a p p e l : ” << n << ” ” << p << e n d l ;
e x i t ( EXIT SUCCESS ) ;
}
v o i d p e r m u t e ( i n t ∗a , i n t ∗b ) {
int c ;
c o u t << ”d e b u t p e r m u t e : ” << ∗ a << ” ” << ∗b << e n d l ;
c=∗a ; ∗ a=∗b ; ∗ b=c ;
c o u t << ” f i n p e r m u t e : ” << ∗ a << ” ” << ∗b << e n d l ;
}
Filière M.A.M. 2ème année - 2008/2009 11 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Passage par référence
Exemple de la permutation
Code source
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
v o i d p e r m u t e ( i n t &, i n t &) ;
i n t n =10 , p =20;
c o u t << ”a v a n t a p p e l : ” << n << ” ” << p << e n d l ;
permute ( n , p ) ;
c o u t << ” a p r e s a p p e l : ” << n << ” ” << p << e n d l ;
e x i t ( EXIT SUCCESS ) ;
}
v o i d p e r m u t e ( i n t &a , i n t &b ) {
int c ;
c o u t << ”d e b u t p e r m u t e : ” << a << ” ” << b << e n d l ;
c=a ; a=b ; b=c ;
c o u t << ” f i n p e r m u t e : ” << a << ” ” << b << e n d l ;
}
Filière M.A.M. 2ème année - 2008/2009 12 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Allocation et désallocation
Les opérateurs new et delete
Ils remplacent malloc, calloc et free.
new et delete
i n t ∗ x=new i n t ( ) ;
i n t ∗ y=new i n t [ 3 ] ;
delete x ;
delete [ ] y ;
Filière M.A.M. 2ème année - 2008/2009 13 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
La surcharge de fonctions
Definition (Surcharge de fonctions)
La surcharge de fonctions est un mécanisme permettant de définir des méthodes
ayant le même nom, mais des listes d’arguments différentes.
Exemple
i n t add ( i n t a , i n t b ) {
r e t u r n a+b ;
}
i n t add ( i n t a , i n t b , i n t c ) {
r e t u r n a+b ;
}
i n t add ( double a , double b ) {
r e t u r n a+b ;
}
Filière M.A.M. 2ème année - 2008/2009 14 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Des structures aux classes
Structures
Structure en C
struct point {
int x ;
int y ;
}
Filière M.A.M. 2ème année - 2008/2009 15 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Des structures aux classes
Structures et fonctions
Structure en C
struct point {
int x ;
int y ;
void i n i t i a l i z e ( int , int ) ;
}
v o i d i n i t i a l i z e ( i n t abs , i n t o r d ) {
x=a b s ;
y=o r d ;
}
Filière M.A.M. 2ème année - 2008/2009 16 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Des structures aux classes
Structures et fonctions membres
Structure en C
struct point {
int x ;
int y ;
void i n i t i a l i z e ( int , int ) ;
}
v o i d p o i n t : : i n i t i a l i z e ( i n t abs , i n t o r d ) {
x=a b s ;
y=o r d ;
}
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
point a ;
a . x =2;
i n i t i a l i z e ( 3 , 5 ) ; // r e j e t a l a c o m p i l a t i o n
a . i n i t i a l i z e (3 ,5);
e x i t ( EXIT SUCCESS ) ;
}
Filière M.A.M. 2ème année - 2008/2009 17 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Objets et classes
Définition et vocabulaire
Definition
Les objets en C++ vérifient le principe d’encapsulation : ils contiennent des
données et des procédures.
La classe est la notion introduite en C++ (et en P.O.O. plus généralement) pour
représenter les objets. On dit que les objets sont des instances de la classe qui les
représente.
Les données sont appelées attributs de la classe et les procédures sont appelées
méthodes ou fonctions membres de la classe.
La notion de classe est une généralisation de la notion de type, et donc de
structure.
Filière M.A.M. 2ème année - 2008/2009 18 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Objets et classes
Protection des données et des traitements
Les classes sont des structures généralisées contenant :
des zones publiques à accès libre : les éléments de cette zone sont accessibles
par tous les éléments d’un logiciel, y compris les parties qui ne sont hors de la
classe;
des zones privées protégées. Les éléments de cette zone ne sont accessibles
que par les éléments de la partie publique de la classe.
On utilise pour cela les mots clés public et private.
Sans précision de la part du programmeur, les éléments d’une classes sont privés
par défaut.
Filière M.A.M. 2ème année - 2008/2009 19 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Objets et classes
Protection des données et des traitements
Exemple : la classe point
class point {
private :
int x ;
int y ;
public :
void i n i t i a l i z e ( int , int ) ;
};
v o i d p o i n t : : i n i t i a l i z e ( i n t abs , i n t o r d ) {
x=a b s ;
y=o r d ;
}
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
point a ;
a . x =2; // r e j e t a l a c o m p i l a t i o n
i n i t i a l i z e ( 3 , 5 ) ; // r e j e t a l a c o m p i l a t i o n
a . i n i t i a l i z e (3 ,5);
e x i t ( EXIT SUCCESS ) ;
}
Filière M.A.M. 2ème année - 2008/2009 20 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Définition des méthodes
Méthodes inline
Exemple : la classe point
class point {
private :
int x , y ;
public :
v o i d p o i n t : : i n i t i a l i z e ( i n t abs , i n t o r d ) {
x=a b s ;
y=o r d ;
}
};
L’opérateur :: est appelé opérateur d’accès.
Le nom d’une fonction membre préfixé par le nom de la classe à l’aide de
l’opérateur :: est appelé nom qualifié de la fonction.
Filière M.A.M. 2ème année - 2008/2009 21 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Appel des méthodes
et avec des pointeurs ?
Exemple : la classe point
class point {
private :
int x , y ;
public :
v o i d p o i n t : : i n i t i a l i z e ( i n t abs , i n t o r d ) {
t h i s −>x=a b s ; t h i s −>y=o r d ;
}
};
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
point a ;
p o i n t ∗b=new p o i n t ( ) ;
a . i n i t i a l i z e (3 ,5);
b−> i n i t i a l i z e ( 1 , 1 ) ;
e x i t ( EXIT SUCCESS ) ;
}
L’attribut caché this désigne un pointeur vers l’objet courant.
Filière M.A.M. 2ème année - 2008/2009 22 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Constructeurs, accesseurs et destructeurs
Définition
Definition (Constructeurs)
Les constructeurs sont des méthodes particulières permettant de contrôler
l’initialisation d’un objet.
Definition (Accesseurs)
Les accesseurs sont des méthodes particulières permettant de récupérer la valeur
des attributs d’un objet.
Definition (Destructeurs)
Les destructeurs sont des méthodes particulières permettant de contrôler la
libération mémoire d’un objet.
Filière M.A.M. 2ème année - 2008/2009 23 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Constructeurs, accesseurs et destructeurs
Règles syntaxiques
Un constructeur est déclaré et défini comme une méthode ayant le même nom que
la classe qui la contient et ayant un certain nombre d’arguments. Contrairement
aux méthodes classiques, il n’a pas de type de retour.
Exemple : la classe point
class point {
private :
int x , y ;
public :
p o i n t : : p o i n t ( i n t abs , i n t o r d ) {
x=a b s ;
y=o r d ;
}
};
Filière M.A.M. 2ème année - 2008/2009 24 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Constructeurs, accesseurs et destructeurs
Règles syntaxiques
Un destructeur est déclaré et défini comme une méthode ayant le même nom que
la classe qui la contient précédé d’un ∼. Il n’a ni arguments ni type de retour
Exemple : la classe point
class point {
private :
int x , y ;
public :
p o i n t : : p o i n t ( i n t abs , i n t o r d ) {
x=a b s ;
y=o r d ;
}
p o i n t : : ˜ p o i n t ( ) {}
};
Filière M.A.M. 2ème année - 2008/2009 25 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Constructeurs, accesseurs et destructeurs
Différents types de constructeurs
le constructeur par défaut est un constructeur qui définit le comportement
par défaut à la déclaration d’une instance de la classe. Il peut se présenter
sous la forme d’un constructeur qui ne prend pas d’arguments ou d’un
constructeur dont les arguments ont tous une valeur par défaut;
le constructeur par valeur est un constructeur qui initialise les attributs d’un
objet à l’aide des valeurs passées en argument;
le constructeur par copie est un constructeur qui prend un unique argument
du même type et le recopie.
Dans la déclaration d’une classe, un constructeur par défaut sans arguments
existe. Il est impératif de le redéfinir si l’on définit un autre constructeur.
Filière M.A.M. 2ème année - 2008/2009 26 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Constructeurs, accesseurs et destructeurs
Le constructeur par copie
La classe point
class point {
private :
int x , y ;
public :
p o i n t : : p o i n t ( i n t a b s =0, i n t o r d =0) { x=a b s ; y=o r d ; }
p o i n t : : p o i n t ( const p o i n t & s o u r c e ) {
x=s o u r c e . x ;
y=s o u r c e . y ;
}
p o i n t : : ˜ p o i n t ( ) {}
};
Filière M.A.M. 2ème année - 2008/2009 27 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Constructeurs, accesseurs et destructeurs
Utilisation des constructeurs
La classe point
i n t main ( i n t a r g c , char ∗ a r g v [ ] ) {
p o i n t a ; // c o n s t r u c t e u r p a r d e f a u t
p o i n t b = a ; // c o n s t r u c t e u r p a r c o p i e
p o i n t c ( a ) ; // c o n s t r u c t e u r p a r c o p i e
p o i n t d ( 2 , 3 ) ; // c o n s t r u c t e u r p a r v a l e u r
p o i n t e = p o i n t ( 3 , 4 ) ; // c o n s t r u c t e u r p a r v a l e u r
p o i n t ∗ f=new p o i n t ( 4 , 4 ) ; // c o n s t r u c t e u r p a r v a l e u r
}
Filière M.A.M. 2ème année - 2008/2009 28 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Constructeurs, accesseurs et destructeurs
Le rôle du destructeur
La classe Date
# i n c l u d e < s t r i n g . h>
c l a s s Date {
private :
i n t j o u r , an ;
char ∗ mois ;
public :
Date : : Date ( i n t j , c h a r ∗ m, i n t a ) {
jour = j ;
an = a ;
m o i s = new c h a r [ s t r l e n (m) + 1 ] ;
s t r c p y ( mois ,m) ;
}
Date : : ˜ Date ( ) { d e l e t e [ ] m o i s ; } // l i b e r e l a zone p o i n t e e par mois
};
Gestion efficace de la mémoire par désallocation explicite des attributs de type
pointeurs d’objets.
Filière M.A.M. 2ème année - 2008/2009 29 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Structure d’un logiciel C++
Conventions d’usage
Pas de réelles contraintes, mais des habitudes qui améliorent la lisibilité :
utiliser des noms explicites pour les classes les attributs et les méthodes;
ne pas utiliser de nombres dans les noms;
si l’on veut utiliser plusieurs mots on les juxtapose en les faisant commencer
par une majuscule, excepté le premier. Par exemple, matricePleine;
puisque l’on peut déclarer des variables à n’importe quel endroit, ne pas les
déclarer dans des boucles;
déclarer systématiquement le constructeur par défaut et le destructeur.
Filière M.A.M. 2ème année - 2008/2009 30 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Structure d’un logiciel C++
fichiers .cpp et .h
le fichier d’en-tête dont l’extension est .h contient le prototype de la
déclaration d’une ou plusieurs classes;
le fichier source d’extension .cpp contient la déclaration de toutes les
fonctions des classes associées dans le fichier d’en-tête. On commencera donc
par inclure celui-ci.
Le fichier source point.cpp
#i n c l u d e ” p o i n t . h ”
p o i n t : : p o i n t ( i n t a b s =0 , i n t o r d =0) {
x=a b s ;
y=o r d ;
}
Une bonne habitude à prendre : 1 classe par fichier et le nom du fichier porte le
nom de la classe.
Filière M.A.M. 2ème année - 2008/2009 31 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Structure d’un logiciel C++
Protection contre l’inclusion multiple
Il peut arriver que l’on inclue plusieurs fois un même fichier d’en-tête. Pour
contrôler ce mécanisme, on peut protéger ceux-ci contre ces inclusions multiples :
Le fichier source point.cpp
#i f n d e f POINT H
#d e f i n e POINT H
class point {
...
};
#e n d i f /∗ POINT H ∗/
Filière M.A.M. 2ème année - 2008/2009 32 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33
Compiler un logiciel C++
3 types de fichiers : les fichiers sources .cpp, les fichiers d’en-tête .h et les fichiers
objets .o issus de la précompilation.
Comment déterminer les dépendances ? 2 cas à considérer :
la déclaration des membres publics n’a pas changé : Cela concerne le cas très
fréquent des modifications internes n’ayant pas de répercussions sur
la manière d’utiliser la classe. On dit que son interface avec
l’extérieur est inchangée. Les programmes utilisant la classe
n’ont pas à être modifiés. Mais ils doivent être recompilés avec le
nouveau fichier d’en-tête correspondant.
la déclaration des membres publics a changé : Cette fois-ci, la manière d’utiliser la
classe peut changer. Les programmes utilisant la classe doivent
le cas échéant être modifiés avant d’être recompilés.
Les fichiers objets issus de la précompilation dépendent donc à la fois des fichiers
sources et des fichiers d’en-tête.
Filière M.A.M. 2ème année - 2008/2009 33 /
Nicolas Kielbasiewicz (C.D.C.S.P./I.S.T.I.L./I.C.J.) Génie Logiciel I 33