Docstoc

formation_cpp_transparents

Document Sample
formation_cpp_transparents Powered By Docstoc
					                   e
Formation C++ avanc´e
           e
ou comment ˆtre les stars du C++

       Raffi Enficiaud
             INRIA



               e
        16-18 f´vrier 2009



         INRIA - IMEDIA
                                      e
                   Formation C++ avanc´e



                                   e e
                     Organisation g´n´rale




Enficiaud (INRIA)              C++            16-18/02/2009   2 / 201
`
A qui s’adresse-t-elle ?
Public
`       e                      e                          e         e
A tout d´veloppeur C++ ayant id´alement quelques mois (ann´es) d’exp´rience.

  e
Pr´requis
La personne doit savoir manipuler le C++, ou en tout cas le ”            c
                                                             C+-” (C++ fa¸on C)




      Enficiaud (INRIA)                C++                        16-18/02/2009   3 / 201
  e
Th`mes de la formation
 1                    e
     vous permettre d’ˆtre le plus autonome possible avec le C++
          Mieux comprendre certaines ”        e
                                      subtilit´s” du langage
                                    e e                   a
          Mieux comprendre ce que g´n`re le compilateur ` partir du code que vous
          e
          ´crivez
 2                                        e
     vous rendre plus productif avec les m´canismes du C++
                                                 e              e
          Utiliser le compilateur pour faire des ´volutions incr´mentales
                        e
          Travailler en ´quipe
                           e e
          Identifier plus pr´cis´ment les sources potentielles de bug
                                  e                  o                  e     e
          Mettre en place des m´canismes de contrˆle de fonctionnalit´ et d’´volution
               e               a
          S’int´grer au mieux ` un ”            e       a
                                     monde ext´rieur” ` votre (partie de) programme




       Enficiaud (INRIA)                   C++                            16-18/02/2009   4 / 201
 e
D´roulement
3 jours intenses de formation :)

Jour 1
         e
      Caf´
         e
      Caf´
      Rappel des bases du C++ (+ exercices)
             e
      (Mini) ´tude de cas

Jour 2
      Les templates (+ exercices)
      La STL (+ exercices)
                        e e
      La programmation g´n´rique (+ exercices)
      Les patrons de conception (+ exercices)

Jour 3
      Organisation de code dans les ”grands” programmes
      Utilisation de Boost
        Enficiaud (INRIA)                C++               16-18/02/2009   5 / 201
                                      e
                   Formation C++ avanc´e



                                     e
                       J1 : C++ avanc´




Enficiaud (INRIA)             C++           16-18/02/2009   6 / 201
              e
J1 : C++ avanc´
Contenu




1                   e
    Quelques difficult´s du langage

2   Rappels sur les instructions

3   Classes

4    e
    H´ritage

5                      e
    Exceptions structur´es

6   Etude de cas




          Enficiaud (INRIA)          C++   16-18/02/2009   7 / 201
                 e
 Quelques difficult´s
du langage




     Enficiaud (INRIA)   C++   16-18/02/2009   8 / 201
        e
Subtilit´ ?
Exemples...


                                  Syntaxe pas trop difficile
                                                                                               ⇒ Langage difficile
                                               e
                                  Fonctionnalit´s importantes

Boucle for
1       int i ;
2       for ( int   i = 0 ; i < 1 0 0 ; ++i ) {
3       }




 e
R´ferences
    Class A                                                                           Utilisation de A

    1      class A {
    2      s t d : : s t r i n g &s ;
    3      public :                                                                   1    A a ( " toto " ) ;
    4      A( s t d : : s t r i n g s ) : s ( s ) {}                                  2    a s s e r t ( a . g i v e m e s ( ) == " toto " ) ; // a s s e r t
    5      const s t d : : s t r i n g& g i v e m e s ( ) const { r e t u r n                          t h r o w s o r bug
                       s ;}
    6      };




               Enficiaud (INRIA)                                                 C++                                                        16-18/02/2009        9 / 201
                                    Types
                        struct
                        union
                        POD
                        typedef
                        extern
 Rappels sur les              o
                        Contrˆle
instructions            Pointeurs
                          ee
                        R´f´rence
                        Garantie de non modification : const
                        Espace de nom
                        Pointeurs sur fonction
                          ee
                        R´f´rences sur fonction
                        volatile




     Enficiaud (INRIA)        C++                        16-18/02/2009   10 / 201
   ınes de caract`re
Chaˆ             e
 e    a
Mˆme l`-dessus il faut revenir...



                      ıne        e
Plusieurs types de chaˆ de caract`re :
 e
D´claration :
    1         ıne
           Chaˆ de type ”classique” : char
    2         ıne       e
           Chaˆ de type ´tendu ”international” : wchar t
                                                                    e
Le type international est souvent utile pour ce qui concerne le syst`me de fichier,
les messages utilisateurs, etc...
1       c h a r ∗ s c o n s t a n t = " blablabla " ;
2       w c h a r t∗ s w i d e = L" wide blablabla " ;


  e
Pr´processeur :
      e                          ınes de caract`res qui se suivent :
Concat`ne automatiquement les chaˆ             e
1       c h a r∗ t o t o = " One big string split " " among small strings "
2          " and among many lines "
3          " ... " ;




               Enficiaud (INRIA)                                 C++           16-18/02/2009   12 / 201
Mot clef ”enum”


 Definition (”enum”)
           e                       e
 Les enum d´finissent un ensemble (r´duit) de valeurs.

 Les enums sont des entiers (constant), mais les entiers ne sont pas des enums.
 1   enum e my enum { // enum                  e
                                           nomm´ e my enum
 2      val1 ,               e
                  // p a r d ´ f a u t =   0
 3      val2 ,               e
                  // p a r d ´ f a u t =   1
 4                                     e
        v a l 4 = 4 // v a l 4 f o r c ´   a
                                           ` 4
 5   };
 6
 7   enum { // enum anonyme
 8     u 1,
 9     u 2,
10   } e1 , e2 ; // e t d o n t e1 e t e2 s o n t d e s i n s t a n c e s
11
12   t y p e d e f /∗enum∗/ e my enum m y s e t e l e m e n t s ;
13
14   v o i d f u n c ( enum e my enum e ) ;
15   void func2 ( my set elements e ) ;




             Enficiaud (INRIA)                                           C++   16-18/02/2009   13 / 201
Structures

Definition (”struct” (ou structure))
                         e         ee
Une structure est une agr´gation d’´l´ments

                      e
La structure est l’ancˆtre de l’objet...
  Structure nomm´e
                e                                                                   Structure anonyme

 1    s t r u c t A { // s t r u c t u r e nomm´e A ( f a c u l t a t i f )
                                                    e
 2        int i ;    // C
                                                                                    1   s t r u c t { // s t r u c t u r e anonyme
 3        int j ;
                                                                                    2       int i ;
 4    private :      // C++
                                                                                    3       float f ;
 5        int p;
                                                                                    4   } b , c ; // b e t c en s o n t d e s i n s t a n c e s
 6    };
                                                                                    5   b . i = c . i = 10;
 7    A a;
                                                                                    6   b . f = c . f = 20. f ;
 8    a . i = 1 0 ; // ok
 9                           e
      a . o = 2 0 ; // a c c ` s i m p o s s i b l e




                   e
Il n’y a aucune diff´rence fonctionnelle entre une structure et une classe.

                e                 e       e
Par compatibilit´ avec le C, l’acc`s par d´faut est public (cf. partie sur les classes)


           Enficiaud (INRIA)                                                   C++                                               16-18/02/2009     14 / 201
Union
Definition (”union”)
                                     e                           a
Une union est une structure particuli`re, n’utilisant qu’un type ` la fois.

Union
   e
  D´claration                                  Utilisation

                                             1      s t r u c t A union {
                                             2          union unnamed union {
                                             3              s t d : : s t r i n g ∗s ;
                                             4              c o n s t c h a r ∗p ;
                                             5              double                d;
                                             6              u n n a m e d u n i o n ( ) : d ( 3 . 1 4 ) {}
                                             7          } current value ;
 1     union u {                             8
 2       int a ;                             9           enum e n u m t y p e {
 3       int j ;                            10              e string ,
 4                                          11              e char ,
 5     private :    // C++                  12              e float
 6       int p;                             13           } current type ;
 7     };                                   14
                                            15           A union ( enum type e = e f l o a t ) : p (
                                                                current type ) , current type (e) ,
                                                                c u r r e n t v a l u e ( ) {}
                                            16             ˜ A union () {
                                            17           }
                                            18
                                            19      };




                   e
Il n’y a aucune diff´rence fonctionnelle entre une structure et une classe.
            Enficiaud (INRIA)             C++                                                        16-18/02/2009   15 / 201
Types POD
Les types ”              e
           natifs” ou agr´gation de type natif




Definition (POD)
POD = Plain Old Data
         e e                                e
Plus pr´cis´ment, tout type ayant un ´quivalent direct avec le C, concernant
l’initialisation, la taille, et l’adressage :
                      e
      toute valeur num´rique (bool, int, double...)
      les enums et les unions
                                                 e
      les structures sans aucun constructeur, op´rateur d’attribution, classe de
               e
      base, m´thode virtuelle, variable non-statique non publique, etc.




         Enficiaud (INRIA)                        C++                  16-18/02/2009   16 / 201
Mot clef ”typedef”


Definition (typedef)
  e                      e               e
Cr´e un alias entre une d´signation compl`te et un nom.

1   typedef struct s my struct toto ;
2   t y p e d e f s t d : : v e c t o r <i n t > i n t v e c t o r ;




Les alias ne prennent aucune ”                         e
                              taille” au moment de l’ex´cution.

  e e
G´n´ralement, les typedefs permettent d’avoir un code plus concis, et dans
                  ee
certains cas d’acc´l´rer les temps de compilation (template).
Nous verrons quelques utilisations du mot clef ”typedef” pendant la partie sur les
templates.




              Enficiaud (INRIA)                                         C++   16-18/02/2009   17 / 201
Mot clef ”extern”

Definition (extern)
                        e                        e ext´
Directive indiquant la d´finition d’un objet allou´ ” erieurement” (ailleurs que la
                    e
ligne indiquant sa d´finition).

         e                                        e                     a
    Les d´clarations de fonction sont extern par d´faut (par opposition ` static )
                                 e                               e               e
    Il est possible d’avoir une d´claration extern suivie de la d´claration concr`te
    1                                                           ı e              e
        e x t e r n s t d : : s t r i n g s ; // a m b i g u¨t ´ e n t r e d ´ c l a r a t i o n e t s t o c k a g e
    2   std : : s t r i n g s ;                e
                                      // l e v ´ e p a r l e mot c l e f e x t e r n
    3                                           e                        e
        v o i d f u n c t i o n 1 ( ) ; // d ´ c l a r a t i o n p a r d ´ f a u t e x t e r n
    4   v o i d f u n c t i o n 1 ( ) {} // d ´ c l a r a t i o n du c o r p s de l a f o n c t i o n
                                                  e



            e      e
    extern d´signe ´galement externe au corps courant
    1   void func ( i n t i ) {
    2      e x t e r n A a1 , a2 , a3 ; // v a r i a b l e s e x t e r n e s au c o r p s de f u n c
    3      switch ( i ) {
    4      c a s e 1 : a1++; b r e a k ;
    5      c a s e 2 : a2++; b r e a k ;
    6      d e f a u l t : a3++; b r e a k ;
    7   }}
    8   A a1 , a2 , a3 ;




        Enficiaud (INRIA)                                                       C++                                     16-18/02/2009   18 / 201
     o
Contrˆle
Boucles ”for”




1   for ( int   i = 0 ; i < 1 0 0 ; i ++)


                                                  e
La variable ”i” est interne au bloc for. Les ”;” d´finissent les champs : il est possible
de ne pas les initialiser :
1   int i = 0;
2   f o r ( ; i < 1 0 0 ; i ++)




           Enficiaud (INRIA)                 C++                         16-18/02/2009   19 / 201
Pointeurs
 e
D´finition



Definition (pointeur)
                              e                                     e
Un pointeur est une variable d´signant un autre objet (l’objet point´)

                                                             e
        Le type du pointeur contient le type de l’objet point´
                     e    a              e         ee
        Le fait d’acc´der ` l’objet point´ est le d´f´rencement du pointeur.

                e          e
La valeur ”0” (z´ro) est l’´quivalent C++ de la macro C NULL. Elle permet de
  e                               ee         e
sp´cifier qu’un pointeur n’a pas ´t´ initialis´ !

1   i n t ∗p ; // p o i n t e u r p o i n t a n t s u r un e n t i e r ( non i n i t i a l i s ´ , v a u t n ’ i m p o r t e q u o i e t donc ´ v e n t u e l l e m e n t
                                                                                               e                                               e
                                    e
                 s u r d e s d o n n´ e s e x i s t a n t e s )
2   i n t ∗u ( 0 ) ; // p a r e i l , m a i s i n i t i a l i s ´ ` 0 ( ne p o i n t e s u r r i e n , mˆme JAMAIS s u r d e s d o n n´ e s e x i s t a n t e s )
                                                                e a                                       e                                  e
3   int i = 10;
4   ∗p = 2 0 ; // BUG HORRIBLE c a r ne s e m a n i f e s t e p a r f o i s p a s
5   p = &i ;           // p p r e n d l ’ a d r e s s e de i
6                                        e e
    a s s e r t (∗p == i ) ; // d ´ f ´ r e n c e m e n t de p
7   ∗p = ∗u ;          // BUG PAS HORRIBLE c a r s e m a n i f e s t e TOUT LE TEMPS !




             Enficiaud (INRIA)                                                     C++                                                         16-18/02/2009           20 / 201
 ee
R´f´rence
 e
D´finition


            ee
Definition (R´f´rence)
 ee                                           eee        ee                    eee
R´f`re un objet existant : alias sur l’objet r´f´r´ (la r´f´rence est l’objet r´f´r´)

Attention !
            ee
       Une r´f´rence est une variable
                                                     eee                  a
       Mais la variable ne peut pas changer d’objet r´f´r´ (contrairement ` un
       pointeur).
              ee                     e             e
Une variable r´f´rence doit toujours ˆtre initialis´e lors de sa construction.


1   int a = 0 , b = 1;
2   i n t &r e f a = a ;
3   s t d : : c o u t << " ref_a = " << r e f a << s t d : : e n d l ;
4
5   ref a = b;
6   s t d : : c o u t << " ref_a = " << r e f a << s t d : : e n d l ;
7   s t d : : c o u t << " but the value of a is now = " << a << s t d : : e n d l ;




            Enficiaud (INRIA)                                             C++           16-18/02/2009   21 / 201
Mot clef ”const”
 e
D´finition



Definition (const)
Mot clef indiquant que l’objet est constant (non mutable ie. non modifiable).


                            e         e   eee
Un objet constant ne peut ˆtre point´ ou r´f´r´ par une variable rompant la
                          e     eee
constance de l’objet point´ ou r´f´r´.


1   i n t const a = 0 , b = 1;
2   // i n t & r e f a = a ; // e r r e u r , r e f a ne g a r a n t i e p a s que a e s t c o n s t a n t
3   i n t const &r e f a = a ;
4   c o n s t i n t &r e f b = b ;
5
6   // i n t ∗p a = &a ;    // e r r e u r , p a ne g a r a n t i e p a s que a e s t c o n s t a n t
7   i n t c o n s t ∗p a = &a ;




                                                       e
Nous verrons plus tard que, pour un objet, seules des m´thodes assurant la
                             e         e
constance de l’objet peuvent ˆtre appel´es.


            Enficiaud (INRIA)                                                C++                              16-18/02/2009   22 / 201
Mot clef ”const”
Utilisation des pointeurs


                                         e             e
       ”const int ” et ”int const” sont s´mantiquement ´quivalents.
       ”const int ∗” et ”int const ∗” sont donc deux pointeurs sur un entier
       constant (le const est avant l’∗).

Ne pas confondre
”const int ∗”, ”int const ∗” et ”int ∗ const”
1   const i n t a ;
2   int b , c ;
3   c o n s t i n t ∗p a = &a ; // p o i n t e u r s u r un e n t i e r c o n s t a n t
4   i n t ∗ c o n s t p b = &b ; // p o i n t e u r ∗c o n s t a n t∗ s u r un e n t i e r ( l a v a r i a b l e p o i n t e u r ne p e u t p a s ˆ t r e c h a n g´ )
                                                                                                                                                  e                e
5
6   p a = &b ; // ok
7   p b = &c ; // e r r e u r , p b ( v a r i a b l e ) e s t c o n s t a n t




                       ee
Rappel : Une variable r´f´rence est toujours constante
                                                 a
int & const n’a pas tellement de sens (identique ` int &).


            Enficiaud (INRIA)                                                    C++                                                      16-18/02/2009          23 / 201
Mot clef ”namespace”
 e
D´finition & syntaxe




 Definition (”namespace”)
            e                         e
 Permet de s´parer un ensemble de d´finitions, types, fonctions... du ”reste du
 monde” (inclusion de librairies/headers externes par exemple).


 1   namespace n s 1 {
 2     i n t const a = 0 , b = 1;
 3     bool fonction1 ( i n t i , in j ) ;
 4   }
 5
 6   namespace n s 2 {
 7     i n t const a = 0 , b = 1;
 8     bool fonction1 ( i n t i , in j ) ;
 9     namespace n s 2 2 {
10         void fonction1 ( float , f l o a t ) ;
11     }
12   }
13   // U t i l i s a t i o n
14   ns2 : : f o n c t i o n 1 ( ns1 : : a , ns2 : : b ) ;




              Enficiaud (INRIA)                               C++    16-18/02/2009   24 / 201
Mot clef ”namespace”
Usage



Alias de namespace
Il est possible d’avoir un alias sur un namespace
1   namespace NS = n s 2 : : n s 2 2 ;
2   NS : : f o n c t i o n 1 ( 0 . 3 2 f , 0 . 3 1 f ) ;




Namespace implicite
Il est possible de dire au compilateur d’aller chercher dans un namespace de
      e
mani`re automatique :
1   u s i n g namespace n s 2 : : n s 2 2 ;
2   fonction1 (0.32 f , 0.31 f ) ;




           a           e                e       oe
Attention ` cette derni`re fonctionnalit´ : le cˆt´ implicite est souvent source
d’erreurs.


              Enficiaud (INRIA)                             C++        16-18/02/2009   25 / 201
Pointeurs sur fonction
Rappels




 Definition (et usage)
 Permet de stocker l’adresse d’une fonction dans une variable (l’attribution de cette
                  e         e
 variable pouvant ˆtre donn´ par une fonction).

                                 u e            e
 La variable peut ensuite (bien-sˆr) ˆtre utilis´e pour appeler la fonction sur
 laquelle elle pointe.
 1   b o o l f u n c 2 ( c o n s t d o u b l e &, i n t , f l o a t &) ;
 2   v o i d f u n c 1 ( b o o l (∗ t o t o ) ( c o n s t d o u b l e &, i n t , f l o a t &) ) {
 3              e                                                                e
        // D ´ c l a r a t i o n de l a v a r i a b l e t o t o , comme ´ t a n t un p o i n t e u r
 4      // s u r une f o n c t i o n de t y p e b o o l ( c o n s t d o u b l e &, i n t , f l o a t &)
 5       float returned f ;
 6
 7      i f ( t o t o ( 0 . 3 9 , 42 , r e t u r n e d f ) )
 8          s t d : : c o u t << " function returned true and the float is = to " << r e t u r n e d f << s t d : : e n d l ;
 9      else
10          s t d : : c o u t << " function returned false " << s t d : : e n d l ;
11   }
12                                    a             e                                    a
     f u n c 1 ( 0 ) ; // e r r e u r ` l ’ e x ´ c u t i o n ( l o r s de l ’ a p p e l ` t o t o ) : f o n c t i o n n u l l e
13                                                                    a
     f u n c 1 (& f u n c 2 ) ; // a t t r i b u t i o n de t o t o ` f u n c 2




              Enficiaud (INRIA)                                                        C++                                          16-18/02/2009   26 / 201
 ee
R´f´rences sur fonction


 Definition (et usage)
                       ee
 Permet de stocker la r´f´rence d’une fonction dans une variable (l’attribution de
                        e        e
 cette variable pouvant ˆtre donn´ par une fonction).

                                  ee
 Contrairement au pointeur, la r´f´rence sur fonction est non-mutable
   e                    ee
 (r´-assignation de la r´f´rence impossible).
 1   b o o l f u n c 2 ( c o n s t d o u b l e &, i n t , f l o a t &) ;
 2   v o i d f u n c 1 ( b o o l (& v a r ) ( c o n s t d o u b l e &, i n t , f l o a t &) ) {
 3              e                                                                e              e e
        // D ´ c l a r a t i o n de l a v a r i a b l e t o t o , comme ´ t a n t une r ´ f ´ r e n c e
 4      // s u r une f o n c t i o n de t y p e b o o l ( c o n s t d o u b l e &, i n t , f l o a t &)
 5       float returned f ;
 6
 7      i f ( var ( 0 . 3 9 , 42 , r e t u r n e d f ) )
 8          s t d : : c o u t << " function returned true and the float is = to " << r e t u r n e d f << s t d : : e n d l ;
 9      else
10          s t d : : c o u t << " function returned false " << s t d : : e n d l ;
11   }
12                                      a
     f u n c 1 ( 0 ) ; // e r r e u r ` l a c o m p i l a t i o n : f o n c t i o n n u l l e n ’ e x i s t e p a s
13                                                                 a
     f u n c 1 ( f u n c 2 ) ; // a t t r i b u t i o n de t o t o ` f u n c 2




              Enficiaud (INRIA)                                                         C++                            16-18/02/2009   27 / 201
Mot clef ”volatile”



Definition (”volatile”)
” volatile ” est un ”modificateur”a indiquant au compilateur que la variable doit
e               e     a
ˆtre lue en m´moire ` chaque acc`s.e
                                 e
  a. modifie le comportement par d´faut d’un type

                   ee                     e                       e a
Ce modificateur a ´t´ initialement utilis´ pour permettre des acc`s ` des variables
                                                      e
externes au processeur sur lequel le programme s’ex´cute (chip annexe par
exemple). Il indique au compilateur, en outre, que la variable en question ne
              a                        e
participe pas ` des optimisations (inf´rences sur sa valeur).
                                                                e          e
Pour ceux/celles qui utilisent les threads, ce modificateur doit ˆtre utilis´ pour les
                    e
variables dont l’acc`s se fait via des threads concurrents.




       Enficiaud (INRIA)                   C++                         16-18/02/2009   28 / 201
Exercice
                        e
Fonction retournant un r´pertoire temporaire
On souhaite avoir une fonction, temporary path, qui retourne une chaˆ      ıne
    e                                     e
repr´sentant le chemin complet d’un r´pertoire temporaire.
On souhaite en outre :
  1                                       a
     que le chemin temporaire soit lu ` partir de la variable d’environnement
     ”TEMP”. Pour cela, on utilisera la fonction C/ANSI ”std :: getenv” (dans
                                          e
     ”<cstdlib>”) qui prend en param`tre le nom de la variable d’environnement
     et qui retourne ”char ∗” Ce retour peut valoir ”
                                .                       NULL” si la variable
     d’environnement n’existe pas.
  2                                                                           e a
     on souhaite que cette variable ne soit lue qu’une seule fois, de mani`re `
      e             e     u       a
     r´duire l’acc`s ”coˆteux” ` l’environnement.
  3  si cette variable n’existe pas, on ne veut pas que notre programme plante. On
                                   e                                    e
     initialisera la variable au r´pertoire contenant le fichier compil´ (c’est super
     laid, mais c’est juste ` titre d’exemple) 1 . Pour cela on se servira de la macro
                             a
     C/ANSI ” FILE ”, de ”std :: string ” et de ”std : string :: rfind ” (on cherchera
            a
     le ’.’ ` partir de la fin).
  4                                  e                                e
     on veut pouvoir modifier ce r´pertoire temporaire de la mani`re suivante :
     1   t e m p o r a r y p a t h ( ) = " mon_nouveau_repertoire " ;


                                                          a
Indice : il s’agit d’une initialisation de type statique, ` l’aide d’une fonction
                    ıne
retournant la chaˆ qu’on souhaite.
         Enficiaud (INRIA)                                          C++   16-18/02/2009   29 / 201
                       Attributs membres
                         e
                       M´thodes membres
                       Attributs statiques
                         e
                       M´thodes statiques
                       Attributs mutables
                       Champs membres
                       this
Classes                Pointeur sur membres
                       Constructeurs de classe
                       Destructeurs
                                       e
                       Surcharge d’op´rateurs
                          e               e
                       Op´rateurs arithm´tiques
                          e
                       Op´rateur d’attribution
                          e
                       Op´rateur de conversion
                          e
                       Op´rateur de fonction




    Enficiaud (INRIA)        C++                   16-18/02/2009   30 / 201
Classe
 e
D´finition




Definition (Classe)
             e               ee             a                               e
Une classe d´clare des propri´t´s communes ` un ensemble d’objets. Elle d´finie
                                      e          e                        e
des attributs (variables membres) repr´sentant l’´tat des objets, et des m´thodes
 e
d´finissant leurs comportements.

Definition (Instance)
                                                e
Une instance de classe est un objet suivant la d´finition de la classe, et dont les
variables membres ont une valeur.




        Enficiaud (INRIA)                C++                           16-18/02/2009   31 / 201
Classe
 e
D´finition (2)


                 ee                                        e
 La classe est l’´l´ment central de la programmation orient´e objet. L’objet est une
 instance de classe.
 Rappel
                    e
 Il n’y a pas de diff´rence entre une classe et une structure.


 1        e
     // D ´ c l a r a t i o n d ’ une c l a s s e
 2   class A {
 3   public :
 4     int i ;
 5     float j ;
 6
 7        A ( ) {}                                                          e
                     // f a b r i q u e / c o n s t r u c t e u r ( p a r d ´ f a u t )
 8
 9                                                        e
          v o i d e v a l u a t e M e ( ) c o n s t ; // m´ thode membre
10   };
11
12
13   A a;           e
               // d ´ c l a r a t i o n d ’ une i n s t a n c e de c l a s s e A




               Enficiaud (INRIA)                                                       C++   16-18/02/2009   32 / 201
Classe
 e
D´claration & Syntaxe



            e                  e
        La d´claration est donn´ par la directive ”class ” ou ”struct ”
                        e
        Elle est suivie ´ventuellement du corps de la classe (accolades)
        Elle se termine par un ”;”
                 e                         e
Si le corps est d´fini, il est possible de d´clarer des objets :
1   c l a s s A {} a , b , c ;
2   s t r u c t B {/∗ . . . ∗/} d , e , f ;


                       e                   e
Si le corps n’est pas d´fini, la directive d´clare une classe dont le corps est
                                                               e
inconnu. Puisque le corps est inconnu, il est impossible de d´clarer des objets de
cette classe :
1   c l a s s A;
2   A a ; // e r r e u r : l a t a i l l e de a e s t i n c o n n u e
3   A ∗a ; // ok : l a t a i l l e du p o i n t e u r e t s o n t y p e s o n t c o n n u s


                       e                                          e
Le corps de la classe d´finie ses membres. Une fois le corps termin´, il n’est pas
possible d’ajouter des membres.


            Enficiaud (INRIA)                                                 C++              16-18/02/2009   33 / 201
Classe
Attributs membres




Definition (attribut)
               e
Les attributs d´finissent le contenu des classes.
                                      a                e      e
Les attributs participent directement ` la taille occup´e en m´moire par la classe.
1   struct A {
2      bool value ;
3                                             e                            e
       b o o l& g e t V a l u e ( ) ; // d ´ c l a r a t i o n de l a m´ thode g e t V a l u e
4      bool                                            e                         e
                g e t V a l u e ( ) c o n s t ; // d ´ c l a r a t i o n de l a m´ thode g e t V a l u e ”c o n s t ”
5   };




            Enficiaud (INRIA)                                                     C++                                    16-18/02/2009   34 / 201
Classe
 e
M´thodes


            e
Definition (m´thodes)
     e        e
Les m´thodes d´finissent le comportement des classes.

                                               e                 e             e
       Le corps de la classe doit contenir la d´claration ou la d´finition compl`te de
           e
       la m´thode membre.
            e                                                  e        a
       Les m´thodes ne participent qu’exceptionnellement (cf. h´ritage) ` la place
            e      e
       occup´e en m´moire par la classe
                      e
       Elle indiquent ´galement si leur appel modifie la classe (ie. si la classe est
       ”mutable” ou non).
1   struct A {
2      bool value ;
3                                             e                            e
       b o o l& g e t V a l u e ( ) ; // d ´ c l a r a t i o n de l a m´ thode g e t V a l u e
4      bool                                            e                         e
                g e t V a l u e ( ) c o n s t ; // d ´ c l a r a t i o n de l a m´ thode g e t V a l u e ”c o n s t ”
5   };


                    e           e                 a    e
Il est possible de d´finir les m´thodes membres ` l’int´rieur du corps de la classe :
                                e
il deviennent alors ”inline ” (d´clarable dans un header par exemple).

            Enficiaud (INRIA)                                                     C++                                    16-18/02/2009   35 / 201
Classe
Attributs static

Definition (”static”)
                        e a                      e             e
Variable membre non li´e ` une instance particuli`re, et partag´e par toutes les
instances d’une classe.

                                     e        e
       Il faut l’initialiser de la mˆme mani`re qu’une variable statique normale, et en
       dehors du corps de la classe
                                                                e            ea     e
       Sauf pour un entier constant, ou un enum, qui peut ˆtre initialis´ ` l’int´rieur
       du corps de la classe
                                   e
       La syntaxe impose la d´claration dans le corps de la classe, et
                                      a    e
       l’attribution/initialisation ` l’ext´rieur du corps de la classe. Attention aux
           e
       acc`s concurrentiels.

Compteur d’instance
1   struct A {
2      static int nb instance ;
3      A ( ) { n b i n s t a n c e ++;}
4   };
5   int A: : nb instance = 0;



           Enficiaud (INRIA)                C++                          16-18/02/2009   36 / 201
Classe
 e
M´thodes statiques

Definition (Statique)
   e                       e a                        e             e
M´thode d’une classe non li´e ` une instance particuli`re, et partag´e par toutes
les instances.
    1   Utilisable par toutes les instances d’une classe
              1                                               e
                   pas besoin d’une instance pour appeler la m´thode
              2                                                  a     e
                   impossible d’attribuer un modificateur ”const” ` la m´thode
    2       e a
        Acc`de ` tous les autres membres statiques de la classe
    3       e a
        Acc`de ` tous les membres non statiques de le classe, si on lui fournit un
        pointeur sur l’instance courante (this)

”factory” (ie. fabrique) de classe
1   struct A {
2                                                         e
       s t a t i c i n t n b i n s t a n c e ; // d ´ c l a r a t i o n de l ’ a t t r i b u t s t a t i c
3      s t a t i c i n t N b I n s t a n c e s ( ) { r e t u r n n b i n s t a n c e ; } // d ´ f i n i t i o n
                                                                                              e
4                                                e
       s t a t i c A c r e a t e ( ) ; // d ´ c l a r a t i o n s e u l e
5   };
6   A A: : create () {
7      n b i n s t a n c e ++; r e t u r n A ;
8   }



              Enficiaud (INRIA)                                                          C++                       16-18/02/2009   37 / 201
Classe
Attributs ”mutable”




Definition (”mutable”)
                                            ,                     a
Variable membre non ”static ” et non ”const” qui ne participe pas ` la gestion du
const de la classe.
                                                 e a                e
La modification d’une variable mutable est autoris´e ` partir d’une m´thode
”const”.

1   struct A {
2      mutable i n t v a l u e ;
3      int  g e t V a l u e ( ) c o n s t { r e t u r n v a l u e ++; }
4   };




                                                       e            e
Les variables ”mutable” permettent de cacher certains d´tails d’impl´mentation
      e
(ex. m´canisme de cache).




            Enficiaud (INRIA)                                              C++   16-18/02/2009   38 / 201
Classe
     o        e
Contrˆle d’acc`s


                                        a
Dans le corps de la classe, on attribut ` chaque membre une restriction sur
     e
l’acc`s, parmi :
        public : le membre est visible de ”tout le monde”
            e e
        prot´g´ (protected) : le membre n’est visible que d’une classe fille (cf.
         e
        h´ritages)
            e
        priv´ (private) : le membre n’est visible que d’une instance strictement du
          e                    e
        mˆme type (qui peut ˆtre l’instance courante)
     e                                  e     e                                         e
Par d´faut, une ”class ” a une visibilit´ priv´e, alors qu’une ”struct ” a une visibilit´
                      e
publique (compatibilit´ avec le C).
1   class A {
2                                        e
      i n t i p r i v a t e ; // p r i v ´
3     void method private () ;
4   public :
5     int i public ;
6     v o i d method ( ) ;
7   } ;




            Enficiaud (INRIA)                 C++                         16-18/02/2009   39 / 201
Classe
Champs membres




Definition (champ)
    e
La d´finition d’un type par l’utilisation de l’instruction ”typedef”.

1   struct A {
2      typedef A t h i s t y p e ;
3      t y p e d e f s t d : : v e c t o r <i n t > s t o r a g e t y p e ;
4      typedef storage type : : value type value type ;
5      /∗ . . . ∗/
6   };


                                   a    e
Les champs de type sont valides ` l’int´rieur de l’espace de nom de la classe.
                                                              e
Rappel : les champs de type ne prennent aucune place en m´moire, et donc ne
                a                e       e
participent pas ` la taille occup´e en m´moire par la classe.




            Enficiaud (INRIA)                                                  C++   16-18/02/2009   40 / 201
Classe
Mot clef ”this”




Definition (this)
”this” pointe sur l’instance courante

1   struct A {
2     int i ; float f ;
3     v o i d A d d i t i o n ( c o n s t A& r ) {
4         t h i s − += r . i ;
                   >i
5         t h i s − += r . j ;
                   >j
6     }
7   } a1 , a2 ;




Sauf...
                                 e
Avant que la classe ne soit compl`tement construite : par exemple avant d’entrer
dans le constructeur.
Nous verrons ce dernier point pendant les constructeurs.



             Enficiaud (INRIA)                        C++           16-18/02/2009   41 / 201
Exercice
 e
D´composition en nombres premiers


Objectif
Avoir une classe, ”                  , e
                   decomposed primes” d´composant un entier en puissances de
nombres premiers.

    1                             e
        un champ ”return type ” pr´cisera le type de stockage. Il sera du type ”map”
    2        e                                             e
        la m´thode ”decompose” prendra un entier en entr´e, et retournera
        ”return type ”
    3                                               e
        une liste initiale de nombre premiers sera d´finie au lancement du programme
        (note : variable statique)
    4                          e         e
        la classe aura une ”m´moire” cach´e, lui permettant d’ajouter des nombres
                  a
        premiers ` sa liste initiale
    5                                                     e
        pour plus de performances, la classe stockera la d´composition en nombre
                                e       a
        premiers des nombres inf´rieurs ` 100.
                           e,                                                               e
On se servira du type ”cach´” ”std :: map<int,int>” (tableau associatif), pour stocker une d´composition. On se servira du type ”    e,
                                                                                                                                 cach´” ”std :: set<int>”
                  e
(ensemble ordonn´), pour stocker les nombres premiers dans l’ordre croissant.
On s’aidera des fichiers ”decomposed primes.[h|cpp]” .



             Enficiaud (INRIA)                                             C++                                                  16-18/02/2009       42 / 201
Exercice
 e
D´composition en nombres premiers

 Rappels sur map (liste associative)
1    #i n c l u d e <map>
2
3             e
     // d ´ c l a r a t i o n d ’ une l i s t e d o n t l e s i n d i c e s s o n t e n t i e r s ,
4                                                                 e
     // e t d o n t l e s a s s o c i a t i o n s s o n t e n t i ` r e s
5    s t d : : map<i n t , i n t > map numbers ;
6
7    map numbers . c o u n t ( 4 2 ) ; // r e t o u r n e 1 s i 42 e s t d a n s l a l i s t e d e s i n d i c e s , 0 s i n o n
8                                                                 a
     map numbers [ 4 2 ] = 7 3 ; // met l a v a l e u r 73 ` l ’ i n d i c e 42
9    i n t i = map numbers [ 4 2 ] ; // met l a v a l e u r de l ’ i n d i c e 42 d a n s i ( s e u l e m e n t s i 42 f a i t                                p a r t i e des i n d i c e s
              de map numbers , s i n o n e r r e u r )




                                 e
 Rappels sur set (ensemble ordonn´)
 1   #i n c l u d e <s e t >
 2
 3            e                                                 e
     // d ´ c l a r a t i o n d ’ un e n s e m b l e o r d o n n´ d ’ e n t i e r s
 4   s t d : : s e t <i n t > p r i m e n u m b e r s ;
 5
 6   p r i m e n u m b e r s . c o u n t ( 4 2 ) ; // r e t o u r n e 1 s i 42 e s t d a n s l a l i s t e d e s i n d i c e s , 0 s i n o n
 7                                                                              a
     p r i m e n u m b e r s . i n s e r t ( 4 2 ) ; // met l a v a l e u r 73 ` l ’ i n d i c e 42
 8   prime numbers . i n s e r t (74) ;
 9
10   // p a r c o u r s de l ’ e n s e m b l e
11   f o r ( s t d : : s e t <i n t > : : c o n s t i t e r a t o r   i t = p r i m e n u m b e r s . b e g i n ( ) , i t e = p r i m e n u m b e r s . end ( ) ;
12       i t != i t e ;
13      ++i t ) {
14       s t d : : c o u t << ∗ i t << " " ;
15   }

               Enficiaud (INRIA)                                                               C++                                                            16-18/02/2009          43 / 201
Pointeurs sur membres
Syntaxe



                                                                     a      e
Les pointeurs sur membre non static doivent indiquer qu’ils pointent ` l’int´rieur
                                e
d’une classe. Il doivent donc sp´cifier le bon espace de nom.
1       struct A {
2           i n t i , j , k , l , m, n ;
3           i n t methode ( f l o a t ) ;
4           i n t methode2 ( f l o a t ) ;
5       };
6       i n t A : : ∗ ; // p o i n t e u r s u r un e n t i e r de A
7       i n t A : : ∗ p i = &A : : i ; // p o i n t e u r ” p i ” s u r un e n t i e r d a n s A , i n i t i a l i s ´ s u r l ’ a d r e s s e de i
                                                                                                                     e
8       i n t (A : : ∗ ) ( f l o a t ) ; // p o i n t e u r s u r une m´ thode de A ( r e t o u r n a n t i n t , e t p r e n a n t un a rg um e nt f l o a t )
                                                                       e
9       i n t (A : : ∗ p methode ) ( f l o a t ) = &A : : methode2 ; // p o i n t e u r p methode i n i t i a l i s ´ s u r A : : methode2
                                                                                                                         e



    1      S’ils pointent sur un membre static, ils sont absolus, n’ont pas besoin de
             e                                                                 e
           sp´cifier l’espace de nom, et n’ont pas besoin d’une instance pour ˆtre
            ee      e
           d´f´renc´s.
    2                                                                               a
           S’ils pointent sur un membre non static, ils sont valident naturellement `
                                  e               ee
           travers une instance (n´cessaire pour d´f´rencer le pointeur).




                Enficiaud (INRIA)                                                  C++                                                       16-18/02/2009         44 / 201
Pointeurs sur membres
Syntaxe (2)



 1   c l a s s A2 {
 2   public :
 3       s t a t i c const i n t i = 0;
 4       const i n t j = 1;
 5       f l o a t m y O p e r a t i o n 1 ( c o n s t A2&) c o n s t ;
 6       f l o a t m y O p e r a t i o n 2 ( c o n s t A2&) c o n s t ;
 7       f l o a t m y O p e r a t i o n 3 ( c o n s t A2&) c o n s t ;
 8       s t a t i c f l o a t m y O p e r a t i o n 4 ( c o n s t A2&) ;
 9       s t a t i c f l o a t m y O p e r a t i o n 5 ( c o n s t A2&) ;
10       static int i ;
11       int j ;
12   };
13   i n t A2 : : i = 0 ;
14
15   // . . .
16
17   // d e f i n i t i o n du t y p e ”
18                                                                    −
     // p o i n t e u r s u r une f o n c t i o n membre ( − c f r e t o u r (∗) ( ) )
19   // d a n s l e namespace A ( c f . A : : ∗ )
20                                                                  e
     // e t l a i s s a n t l e namespace i n c h a n g ´ ( c o n s t f i n a l )
21                                                                  e e
     // r e t o u r n a n t f l o a t e t p r e n a n t un r ´ f ´ r e n c e c o n s t s u r A
22   t y p e d e f f l o a t ( A2 : : ∗ o p e r a t o r t y p e ) ( c o n s t A2&) c o n s t ;
23
24           e
     // d ´ c l a r a t i o n de v a r i a b l e s
25   o p e r a t o r t y p e v1 = &A2 : : myOperation1 , v2 = &A2 : : m y O p e r a t i o n 3 ;
26
27                                 e                                      a
     // p o i n t e u r s u r m´ thode s t a t i c , i d e n t i q u e ` un p o i n t e u r s u r f o n c t i o n
28   f l o a t (∗ v4 ) ( c o n s t A2&) = &A2 : : m y O p e r a t i o n 5 ;




                Enficiaud (INRIA)                                                  C++                               16-18/02/2009   45 / 201
Pointeurs sur membres
Syntaxe (3)




 1   // a p p e l s
 2   A2 a1 ;
 3   A2 ∗a2 = &a1 ;
 4   ( a1 .∗ v1 ) ( a1 ) ;
 5   a2−  >∗v2 ( a1 ) ;        e
                           // m´ thode non s t a t i c
 6
 7   v4 ( a1 ) ;          e
                      // m´ thode s t a t i c
 8
 9   i n t A2 : : ∗ p j = &A2 : : j ;
10   i n t ∗ p i = &A2 : : i ;
11   a1 .∗ p j = 1 0 ; // v a r i a b l e non s t a t i c
12   ∗p i = 20;         // v a r i a b l e s t a t i c




              Enficiaud (INRIA)                              C++   16-18/02/2009   46 / 201
Constructeurs
 e
D´finition

Definition (Constructeur)
                                            a
Le constructeur initialise la classe, c’est-`-dire ses ressources et ses variables
                    e      e          e
membres. Il est repr´sent´ par la m´thode portant le nom de la classe. Il peut ˆtree
        e
surcharg´.

Definition (liste d’initialisation)
                                            e            e
Il s’agit d’une liste apparaissant juste apr`s la parenth`se fermante du
                           c            .
constructeur, et commen¸ant par ” :” Elle se termine avec l’accolade ouvrante du
constructeur.


1   struct A {
2      int i , j , k
3      A( ) :           e
                   // d´ b u t de l a l i s t e d ’ i n i t i a l i s a t i o n
4         i (0)
5         , j (1)
6         , k (2)
7      {        // f i n de l a l i s t e d ’ i n i t i a l i s a t i o n
8      }
9   };




            Enficiaud (INRIA)                                                      C++   16-18/02/2009   47 / 201
Constructeurs
Rappel




`
A ne pas confondre...
1   A a;                 e                                                                                              e                      e
                    // d ´ c l a r a t i o n d ’ un o b j e t a de t y p e A : l e c o n s t r u c t e u r p a r d ´ f a u t e s t u t i l i s ´
2   A a () ;                 e                                                               e
                      // d ´ c l a r a t i o n d ’ une f o n c t i o n a , s a n s p a r a m ` t r e s e t r e t o u r n a n t un o b j e t de t y p e A




               Enficiaud (INRIA)                                                  C++                                                        16-18/02/2009   48 / 201
Constructeurs
     e
Par d´faut // par recopie


                             e
Definition (Constructeur par d´faut)
                  e
Constructeur appel´ sans arguments

Definition (Constructeur par recopie)
                                      ee       a
Constructeur avec comme argument une r´f´rence ` une autre instance de la
 e
mˆme classe
1   class A {
2      s t d : : s t r i n g ∗s ;
3   public :
4      A ( ) : s ( 0 ) {} // c o n s t r u c t e u r p a r d ´ f a u t
                                                             e
5      A( c o n s t A& a ) : s ( new s t d : : s t r i n g (∗ a . s ) ) {} // c o n s t r u c t e u r p a r r e c o p i e
6   };




Attention ! !
        e                      e e
Si non d´fini, le compilateur g´n`re *automatiquement* des constructeurs par
 e
d´faut (si possible) et/ou par recopie (si possible).


            Enficiaud (INRIA)                                                   C++                                          16-18/02/2009   49 / 201
Constructeurs
Construction des variables membres




Les variables membres sont construites dans la liste d’initialisation.
1   struct A {
2      int i , j , k
3      A( ) :           e
                   // d´ b u t de l a l i s t e d ’ i n i t i a l i s a t i o n
4         i (0)
5         , j (1)
6         , k (2)
7      {        // f i n de l a l i s t e d ’ i n i t i a l i s a t i o n
8      }
9   };




Ordre de construction
                                                               e
L’ordre de construction des variables membres suit l’ordre de d´claration dans la
classe.
               e
Rappel : les m´thodes ne sont pas des variables (et donc n’influencent pas la taille
de la classe).



            Enficiaud (INRIA)                                                      C++   16-18/02/2009   50 / 201
Constructeurs
Construction des variables membres (2)


                       e
Il existe bien des mani`res d’initialiser un objet...

                  e
Construction par d´faut
                                                              e
Si le constructeur d’une variable membre n’est pas appel´ explicitement dans la
liste d’initialisation, et si la variable n’est pas de type POD, alors son constructeur
      e
par d´faut est appel´.  e

1   class A {
2      std : : s t r i n g s ;
3      int           i , j;
4   public :
5      A ( ) : s ( ) , i ( 0 ) {}
6                                   e                                                                                                  e
       // j , non i n i t i a l i s ´ ( v a u t n ’ i m p o r t e q u o i ) c a r i n t n ’ a p a s de c o n s t r u c t e u r p a r d ´ f a u t
7   };




Il est plus performant d’initialiser les variables membres directement dans la liste
                       o
d’initialisation, plutˆt que dans le corps du constructeur (bonne pratique :
l’initialisation n’est faite qu’une fois).



            Enficiaud (INRIA)                                                      C++                                                         16-18/02/2009   51 / 201
Constructeurs
     o        e
Contrˆle d’acc`s

     e     e          e
Les mˆmes r`gles d’acc`s s’appliquent au constructeur :

Definition (constructeur public)
Constructeur appelable par ”tout le monde”

                            e
Definition (constructeur priv´)
                                                      e
Constructeur appelable uniquement par la classe elle-mˆme

1   class A {
2      s t d : : s t r i n g ∗s ;
3      A( c o n s t A&) ;         // i n t e r d i t l ’ u t i l i s a t i o n i m p l i c i t e du c o n s t r u c t e u r p a r r e c o p i e
4   public :
5      A ( ) : s ( 0 ) {}                  e                       e                                                e
                                    // d ´ f i n i e t i m p l´ m e n t e l e c o n s t r u c t e u r p a r d ´ f a u t
6   };




                            e e
Definition (constructeur prot´g´)
                                                            e
Constructeur appelable uniquement par une classe fille (cf. h´ritage)


             Enficiaud (INRIA)                                                          C++                                                        16-18/02/2009   52 / 201
Exercice
”Copy constructible”


Objectif
Faire en sorte que la classe suivante soit ”                   ,      a
                                            copy constructible” c’est-`-dire qu’elle
    e
impl´mente le constructeur par recopie.

  Classe                                                                               Test

  1    s t r u c t A union {
  2        union {
  3            s t d : : s t r i n g ∗s ;
  4            c o n s t c h a r ∗p ;
  5            double              d;
                                                                                       1      A union a ;
  6        } current value ;
                                                                                       2      s t d : : c o u t << a ;
  7        enum {
                                                                                       3
  8            e string ,
                                                                                       4      a . c u r r e n t t y p e = A union : : e s t r i n g ;
  9            e char ,
                                                                                       5      a . c u r r e n t v a l u e . s = new s t d : : s t r i n g ( " this is
 10            e float
                                                                                                          a string " ) ;
 11        } current type ;
                                                                                       6      s t d : : c o u t << a ;
 12
                                                                                       7
 13         const i n t some int ;
                                                                                       8      A union b = a ;
 14
                                                                                       9      s t d : : c o u t << b ;
 15         A union () : some int (0) , c u r r e n t t y p e (
                       e f l o a t ) , c u r r e n t v a l u e ( ) {}
 16         ˜ A u n i o n ( ) { i f ( c u r r e n t t y p e == e s t r i n g )
                       delete current value . s ;}
 17    };




             Enficiaud (INRIA)                                                    C++                                                        16-18/02/2009          53 / 201
Exercice
”Copy constructible” (2)



Objectif
Faire en sorte que la classe suivante soit non ”copy constructible”.

  Classe                                                                  Test

  1    s t r u c t A union {
  2        union {
  3            s t d : : s t r i n g ∗s ;
                                                                          1      A union a ;
  4            c o n s t c h a r ∗p ;
                                                                          2      s t d : : c o u t << a ;
  5            double              d;
                                                                          3
  6        } current value ;
                                                                          4      a . c u r r e n t t y p e = A union : : e s t r i n g ;
  7        enum {
                                                                          5      a . c u r r e n t v a l u e . s = new s t d : : s t r i n g ( " this is
  8            e string ,
                                                                                             a string " ) ;
  9            e char ,
                                                                          6      s t d : : c o u t << a ;
 10            e float
                                                                          7
 11        } current type ;
                                                                          8      A union b = a ;
 12
                                                                          9      s t d : : c o u t << b ;
 13         A union () : some int (0) , c u r r e n t t y p e (
                   e f l o a t ) , c u r r e n t v a l u e ( ) {}
 14    };




             Enficiaud (INRIA)                                       C++                                                        16-18/02/2009          54 / 201
Constructeurs
Variable membres const




Variables membres const
           e         e     e
Ne peuvent ˆtre chang´e apr`s instanciation de la classe

Donc...
        e             e
Doivent ˆtre initialis´e dans la liste du constructeur
1   class A {
2        const i n t  i , j;
3   public :
4      A( ) : i (0) {
5         j = 1 ; // e r r e u r
6      }
7   };




           Enficiaud (INRIA)              C++               16-18/02/2009   55 / 201
Constructeurs
                  ee
Variable membres r´f´rence
     ee                e             e
Les r´f´rences doivent ˆtre initialis´es dans la liste d’initialisation.
Attention
               ee                 ee
Les attributs r´f´rences doivent r´f´rer soit :
                              e          e
        des objets dont la dur´e de vie d´passe celle de la classe !
        soit des objets temporaires ”                                        ee
                                     automatiques” (ce qui veut dire que la r´f´rence
        est ”const”)

                 ee        e                               e             e
Les ”variables” r´f´rences ´tant constantes, elles doivent ˆtre initialis´es dans la
                    e
liste constructeur ´galement.

Trouver le bug
1    struct A {
2       s t d : : s t r i n g &s
3       A( s t d : : s t r i n g s ) : s ( s ) {}
4    };
5
6   A a ( " value__ " ) ;
7   i f ( a . s == " value__ " )
8       s t d : : c o u t << " compilo bugg´ ! " << s t d : : e n d l ;
                                           e

                                                                                c                 e
Ce code fonctionne sous GCC 4.0.1 MacOSX et non sous Visual Studio 2008... mais ¸a reste un bug, mˆme s’il fonctionne sur certaines architectures


             Enficiaud (INRIA)                                             C++                                               16-18/02/2009       56 / 201
Constructeurs
Restriction des conversions : mot clef ”explicit”




Definition (”explicit”)
                                                        e          e
Force l’appel du constructeur avec les types exacts pass´s en param`tres de
celui-ci.
                                                        e
Aucun ”trans-typage” (conversion implicite) n’est effectu´ pour les constructeurs
explicites.
1   struct A {
2      e x p l i c i t A( i n t , c o n s t f l o a t &) ;
3      e x p l i c i t A( l o n g , c o n s t d o u b l e &) ;
4   };




             Enficiaud (INRIA)                                    C++   16-18/02/2009   57 / 201
Constructeurs
Mise en garde

Limite sur l’utilisation de this
                                    a                                 e
La classe est totalement construite ` la fin du bloc du constructeur (h´ritage de
classe).

Donc ...
On ne peut pas utiliser this correctement

Mais ...
                               a       e
Les variables membres existent ` l’entr´e du bloc du constructeur




        Enficiaud (INRIA)               C++                          16-18/02/2009   58 / 201
Destructeurs
  e
Pr´sentation

Objet
    1         e                                   a
             D´truit les objets qui appartiennent ` la classe
    2           e       e           e
             Lib`re la m´moire allou´e par la classe
    3         e         e
             G`re la dur´e de vie des pointeurs.

             e                                               e           e
Il porte le mˆme nom que la classe, et n’a jamais de param`tres en entr´e. Il faut
                   e
l’appeler avec l’op´rateur ”delete ” et (pratiquement) jamais directement.

Syntaxe
1       struct A {
2         ˜A ( ) {}
3       };




Dans un programme stable, le destructeur est TOUT AUSSI important que le
                                         e
constructeur (ou n’importe quelle autre m´thode).

                 e                                     e
Les objets sont d´truits dans l’ordre inverse de leur d´claration lors de l’accolade
fermante du destructeur.
               Enficiaud (INRIA)                    C++                 16-18/02/2009   59 / 201
Exercice
Classe de matrice




     e
Enonc´
Ecrire une classe de matrice ”matrice d” de type double. Le constructeur de la
                      e
classe aura pour param`tres deux entiers indiquant la taille (allocation dynamique).




        Enficiaud (INRIA)                C++                          16-18/02/2009   61 / 201
                        e
Classes & surcharge d’op´rateurs
Introduction




             e
Definition (op´rateurs)
Fonctions unaires ou binaires
             e       e                            e e
Lorsqu’on d´fini l’op´rateur d’une classe, on dit g´n´ralement qu’on surcharge cet
  e                                      e                   e
op´rateur. Ce sous-entend que si ces op´rateurs ne sont pas d´finis, le compilateur
               e e
essaie de les g´n´rer automatiquement.
             e           ee
Plusieurs op´rateur d’int´rˆt, exemple :
1   o p e r a t o r= ;    // a t t r i b u t i o n
2   o p e r a t o r==    ; o p e r a t o r != ; o p e r a t o r <; o p e r a t o r > ; . . . // c o m p a r a i s o n
3   o p e r a t o r++                       −                       e                        e e                           e
                         ; o p e r a t o r− ; // a u t o i n c r ´ m e n t a t i o n e t d ´ c r ´ m e n t a t i o n ( p r ´ ou p o s t )
4   o p e r a t o r+ ;    o p e r a t o r +=; o p e r a t o r− ; o p e r a t o r −=; . . . // a r i t h m ´ t i q u e
                                                                                                           e
5   o p e r a t o r∗ ;            e e
                          // d ´ f ´ r e n c e m e n t ou m u l t i p l i c a t i o n
6   operator ! ;                  e
                          // n ´ g a t i o n




             Enficiaud (INRIA)                                                         C++                                                   16-18/02/2009   62 / 201
                        e
Classes & surcharge d’op´rateurs
          e
Types d’op´rateurs
                          e
Il existe deux types d’op´rateurs :
   1        e
      les op´rateurs unaires : ils n’impliquent qu’un seul objet, et donc ne prennent
                    e
      pas de param`tres
      1   struct A {
      2     A operator ! ( ) ;
      3   };


  2         e
      les op´rateurs binaires : ils impliquent deux objets : l’objet courant, implicite
         a                                                                    e
      et ` gauche de l’expression, et l’objet argument (explicite, en param`tre)
      1   struct U {};
      2   struct A {
      3      A o p e r a t o r +( c o n s t U&) ;
      4   };
      5   A a, b;
      6   U u;
      7   b = a + u;                                      a
                               // a ( de t y p e A) e s t ` g a u c h e de u ( de t y p e U)




                    e          e                   e
Si l’on souhaite d´finir un op´rateur alors que l’op´rande gauche est d’un autre
                                e
type, il faut faire appel aux m´thodes amies.

                                  e           e                  e        e
Dans une expression, le sens de l’´valuation d´pend de la priorit´ de l’op´rateur.
          Enficiaud (INRIA)                                            C++                      16-18/02/2009   63 / 201
Exercice
  e              e
Op´rateurs arithm´tiques



     e
Enonc´
Pour une matrice :
                  e
     Ecrire les op´rateurs d’addition, de multiplication avec un double
                e
     Ecrire l’op´rateur de multiplication avec une autre matrice

     e
Enonc´
                e                              e
     Ecrire l’op´rateur d’addition entre deux d´compositions en nombre premier
     (classe ”decomposed primes”   ).
                e                             e
     Ecrire l’op´rateur d’addition entre une d´composition et un entier
                e
     Ecrire l’op´rateur de multiplication (deux ”decomposed primes” et un entier)
                e
     Ecrire l’op´rateur de division (deux ”decomposed primes” et un entier) : on se
                                      e
     permet d’avoir des exposants n´gatifs



        Enficiaud (INRIA)                C++                          16-18/02/2009   64 / 201
  e
Op´rateur d’attribution
 e
D´finition & syntaxe




Definition (”operator=”)
  e                               e                   a
Op´rateur permettant de changer l’´tat de la classe grˆce au signe =.

Syntaxe
1   struct A {
2     A& o p e r a t o r =( c o n s t A&) ;
3   };




       e
Cet op´rateur est utile lorsque la copie n’est pas triviale (ie. typiquement avec
                                    ee                                 e
membres de type pointeurs et/ou r´f´rences). Souvent, lorsque l’op´rateur ne peut
e     e ee                                      e
ˆtre g´n´r´ automatiquement, le compilateur ´met un avertissement (warning).




            Enficiaud (INRIA)                  C++                  16-18/02/2009   65 / 201
  e
Op´rateur d’attribution
           e
Transitivit´


           e
Transitivit´ : a = b = c = . . . = z
= est transitif
        e               e
Il doit ˆtre possible d’´crire :
1   s t r u c t A {/∗ . . . ∗/} a1 , a2 , a3 ;
2   a1 . i n i t ( 4 2 ) ; // i n i t i a l i s a t i o n
3   a2 = a3 = a1 ;           // t r a n s i t i v i t ´ e




Donc
                 e                          e         ee
Le retour de l’op´rateur d’attribution doit ˆtre une r´f´rence sur l’instance.
Exemple :
1   A& A : : o p e r a t o r =( c o n s t A& r ) {
2     i = r .i;
3     return ∗t h i s ;
4   }




             Enficiaud (INRIA)                               C++       16-18/02/2009   66 / 201
  e
Op´rateur d’attribution
Remarque : auto-attribution (1)




         e
Il faut g´rer le cas a = a
      a                  e               e
C’est-`-dire ... il doit ˆtre possible d’´crire :
1   s t r u c t A { s t d : : s t r i n g ∗s ; A& A : : o p e r a t o r =( c o n s t A& r ) ; } a ;
2   a = a;          // auto−a t t r i b u t i o n


sans danger pour la classe a ;

        a
Exemple ` ne pas faire...
1   A& A : : o p e r a t o r =( c o n s t A& r ) {
2     delete s ;
3     s = new s t d : : s t r i n g ( r . s ) ;    // s n ’ e x i s t e p l u s    s i &r     == t h i s
4     return ∗t h i s ;
5   }




             Enficiaud (INRIA)                                                     C++                      16-18/02/2009   67 / 201
  e
Op´rateur d’attribution : remarques
Auto-attribution (2)



Donc...
  1    e
      g´rer explicitement le cas a = a par ”this”
      1   A& A : : o p e r a t o r =( c o n s t A& r )
      2   {
      3     i f ( t h i s == &r ) r e t u r n ∗ t h i s ;
      4     delete s ;
      5     s = new s t d : : s t r i n g ( r . s ) ;
      6     return ∗t h i s ;
      7   }


  2                         e
      changer l’ordre des op´rations pour avoir une gestion implicite
      1   A& A : : o p e r a t o r =( c o n s t A& r )
      2   {
      3     s t d : : s t r i n g s t m p = new s t d : : s t r i n g ( r . s ) ;
      4     delete s ;
      5     s = s tmp ;
      6     return ∗t h i s ;
      7   }




          Enficiaud (INRIA)                                                    C++   16-18/02/2009   68 / 201
  e
Op´rateur d’attribution
           e ee
Code auto-g´n´r´




Le compilateur ”sait” faire des choses :
                                                                              e
Si les types contenus dans la structure/classe sont de type triviaux ou poss`dent
                                    e                                    e
tous un constructeur par recopie (d´fini ou trivial), alors il n’est pas n´cessaire de
 e         e                       e
d´finir l’op´rateur d’attribution (mˆme remarque s’applique au constructeur par
recopie).

Donc :
  e          e                                                    e
N’´crire l’op´rateur d’attribution seulement quand vous le jugez n´cessaire
                      ee
(membres pointeur/r´f´rence/const).




       Enficiaud (INRIA)                  C++                           16-18/02/2009   69 / 201
  e
Op´rateur d’attribution
Classe de matrice




     e
Enonc´
                e
     Ecrire l’op´rateur d’attribution de la matrice avec une autre matrice : si les
                                 e
     matrices ne sont pas de mˆme taille, alors on fait la recopie.
                e
     Ecrire l’op´rateur d’attribution entre une matrice et une autre, entre une
     matrice et un entier.




        Enficiaud (INRIA)                 C++                          16-18/02/2009   70 / 201
  e
Op´rateur de conversion
 e
D´finition


Definition (”operator T”)
  e            e
Op´rateur appel´ lors d’un cast explicite vers un type particulier.

       e            e     e                                     e
Cet op´rateur peut ˆtre tr`s pratique dans certains cas. Il ne d´finit pas de type de
retour, puisque ce type est implicite par le cast.

Syntaxe
1   s t r u c t A { o p e r a t o r i n t ( ) { /∗ c a s t de A v e r s e n t i e r   i n t ∗/ } } ;




Exercice
                                                       e
Ecrire une classe qui affiche des informations sur son ´tat lorsqu’on la transforme
       ıne          e
en chaˆ de caract`re. On utilisera par exemple la classe ” decomposed primes” et
                                   e e
la classe ”matrice d” (exercices pr´c´dents - pour ”decompose primes” voir la
fonction fournie dans les fichiers).


            Enficiaud (INRIA)                                                  C++                      16-18/02/2009   71 / 201
                        e
Classes : surcharge d’op´rateur
  e
Op´rateur de fonction



Definition (”operator()”)
  e               a
Op´rateur donnant ` la classe l’interface d’une fonction.

Syntaxe
1   struct A {
2      bool o p e r a t o r ( ) ( double , f l o a t , i n t ) const ;
3      f l o a t operator () ( int , f l o a t ) ;
4   };
5
6   A a;
7   a ( 0 . 3 4 , .32 f , 42) ;
8   a (42 , .32 f ) ;




Exercice
           e                                            e      a  ee
Ecrire l’op´rateur de fonction de la matrice, afin d’acc´der ` ses ´l´ments.
Question subsidiaire : pourquoi ne pas utiliser l’”operator [] ”?



            Enficiaud (INRIA)                                             C++   16-18/02/2009   72 / 201
                       Introduction
                             o
                       Contrˆle d’acc`se
                                e    e
                       Visibilit´ & d´sambigu¨ ısation
                       Construction et destruction
 e
H´ritage               Conversions
                         e
                       H´ritage multiple
                       Classes virtuelles
                       Classes virtuelles pures
                       Interfaces




    Enficiaud (INRIA)         C++                         16-18/02/2009   73 / 201
 e
H´ritage
 e
D´finition



              e
Que signifie h´ritage ?
                   e
Soit une classe A h´ritant d’une classe B :
    1         e
           A h´rite partiellement du comportement de B
    2          e        e                                             e
           A ”h´rite” (s´mantiquement parlant) de B par le biais des m´thodes de B
    3          e    e                                               e
           A h´rite ´galement des attributs de B, s’ils sont marqu´s comme tel,
                 a                                      e                e e
           c’est-`-dire si les attributs de B ont un acc`s public ou prot´g´.
    4         e
           A h´rite des champs de type de B

Syntaxe :
1       class B {};
2       c l a s s A : [ a c c ` s ] B { } ; // a c c ` s : p u b l i c , p r o t e c t e d ou p r i v a t e ( ou r i e n )
                              e                      e




                Enficiaud (INRIA)                                                   C++                                       16-18/02/2009   74 / 201
 e
H´ritage
     o        e
Contrˆle d’acc`s




         o        e                e                                      e a
 Le contrˆle d’acc`s d’une classe m`re s’applique aux classes filles. L’acc`s ` la
         e        e
 classe m`re peut ˆtre davantage restreint.

 1   class B {
 2                                                           e
        s t d : : s t r i n g s ; // a t t r i b u t p r i v ´
 3   protected :
 4                                                  e
        i n t v a l u e ; // a t t r i b u t a c c ´ s s i b l e aux c l a s s e s     e
                                                                                     h ´ r i t a n t de B
 5   public :
 6      int public value ;
 7      void printMe () const ;
 8   };
 9
10   class A : public B {
11                               e         a                    e       a
        // A ne p e u t a c c ´ d e r ` s m a i s p e u t a c c ´ d e r ` v a l u e e t p u b l i c v a l u e
12      // v a l u e e s t p r o t e c t e d
13      // p u b l i c v a l u e e s t p u b l i c
14   };
15
16   A a;
17   a . v a l u e = 1 0 ; // e r r e u r , v a l u e e s t p r o t e c t e d
18   a . printMe () ;                e                                        e
                           // a h ´ r i t e de c e comportement , c a r l ’ h ´ r i t a g e de B e s t p u b l i c




              Enficiaud (INRIA)                                                       C++                             16-18/02/2009   75 / 201
 e
H´ritage
     o        e
Contrˆle d’acc`s (2)




        e              e e         e
Si l’acc`s n’est pas sp´cifi´, par d´faut il est :
      private pour les classes
      public pour les structures

 e
H´ritage de type
                        e        e      e
      public : visibilit´ inchang´e (acc`s aux membres public et protected)
                         e                                      e                 e
     private : la totalit´ des membres accessibles (ie. non priv´s) de la classe m`re
                     e
     deviennent priv´s
      protected : public devient protected (private toujours inaccessible)




        Enficiaud (INRIA)                 C++                          16-18/02/2009   76 / 201
 e
H´ritage
         e
Visibilit´

Les attributs de la classe courante sont visibles prioritairement sur celles de la
         e
classe m`re.
     e                                      e
Les m´thodes peuvent donc boucler sur elle-mˆme !
     D´finitions
      e                                                                            Usage

     1      struct A {
     2         typedef int value type ;
     3         v a l u e t y p e doSthg ( ) c o n s t ;
     4      };
     5
     6      struct B : public A {
                                                                                   1      B b;
     7         typedef f l o a t value type ;
                                                                                   2      B : : v a l u e t y p e v a l = b . doSthg ( ) ; // v a l e s t
     8         typedef A : : value type a value type ;
                                                                                                       float , boucle infiniment
     9         v a l u e t y p e doSthg ( ) c o n s t {
    10            doSthg ( ) ; // a p p e l l e B : : doSthg au l i e u de
                               A : : doSthg
    11            // do some o t h e r t h i n g s
    12         }
    13      };




                       ee                   a      e
Il est possible de se r´f´rer explicitement ` une m´thode ou un attribut de l’une
               e                o         e
des classes m`res (si les contrˆles d’acc`s le permettent), par la syntaxe suivante :
1        B : : v a l u e t y p e doSthg ( ) c o n s t {
2           A : : doSthg ( ) ; // a p p e l l e A : : doSthg au l i e u de A : : doSthg
3            // do some o t h e r t h i n g s
4        }

                 Enficiaud (INRIA)                                            C++                                                     16-18/02/2009          77 / 201
 e
H´ritage
Constructeurs



                                       e
Une classe fille contient la classe m`re (c’en est une extension). Donc, si la classe
                                            e           e
fille est construite, il faut que la classe m`re le soit ´galement.

                e
Constructeur : r`gle
                           e                  e            e
     Le constructeur par d´faut de la classe m`re est appel´ avant l’initialisation
     du premier (ie. de tous) membre de la classe fille.
                                                                           e
     La classe fille peut appeler un constructeur particulier de la classe m`re, dans
     sa liste d’initialisation
                    e        e                        e
En fait, la classe m`re peut ˆtre vue (en terme d’impl´mentation) comme une
variable membre avant toutes les autres.

         o         e                                e                 a
Les contrˆles d’acc`s du constructeur de la classe m`re est identique ` n’importe
quelle autre membre




        Enficiaud (INRIA)                 C++                          16-18/02/2009   78 / 201
 e
H´ritage
Constructeurs : exercice




                e                                        e
Soit la classe m`re suivante, ouvrant un fichier dans le r´pertoire courant :
1   class FileUtil {
2   public :
3     // i n i t i a l i s e l a c l a s s e a v e c l e f i c h i e r non o u v e r t f i l e n a m e
4     F i l e U t i l ( c o n s t s t d : : s t r i n g &f i l e n a m e ) {/∗ . . . ∗/}
5
6        /∗ . . . ∗/
7   };


Une fois le fichier ouvert, la classe propose des manipulations de ce fichier (or de
propos ici).
                                        e           e
Nous souhaitons une nouvelle classe h´ritant ces m´thodes de manipulation, mais
                             e      e
ouvrant les fichiers de mani`re diff´rente.
                    e                       e
Note : Nous consid´rerons que la classe m`re stocke un handle de fichier dans la
variable membre ”FILE ∗ m file handler ” Elle offrirait ` ses classes filles un
                                          .            a
constructeur particulier...




              Enficiaud (INRIA)                                                    C++                    16-18/02/2009   79 / 201
 e
H´ritage
Destructeurs




               e
Destructeur : r`gle
                                e            e    e
Le destructeur de la classe m`re est appel´ apr`s la destruction de tous les membre
                               e
de la classe fille (lors de l’ex´cution de l’accolade fermante de la classe fille).

      a                                    e          ee
C’est ` dire, dans l’ordre inverse de la cr´ation des ´l´ments.




        Enficiaud (INRIA)                 C++                        16-18/02/2009   80 / 201
 e
H´ritage
Conversions




Il est possible de couper une classe, mais il n’est pas possible d’inventer des
extensions de classe.
                                                e
Une classe fille est une extension de sa classe m`re. Il est donc possible de
  e                                        e
pr´senter la partie concernant sa classe m`re.
1   // A f i l l e de B
2   A a;
3   B ∗p b = &a ; // ”du p l u s p r ´ c i s au p l u s g ´ n ´ r a l ”
                                     e                    e e
4   B& r e f b = a ;


                                                           e
L’inverse n’est pas vrai, car il faudrait inventer des donn´es manquantes :
1   // B f i l l e de A
2   A a;
3   B ∗p b = &a ; // e r r e u r de c o m p i l a t i o n : l e c o m p i l a t e u r ne s a i t p a s
4   B& r e f b = a ; // s i c e s i n s t r u c t i o n s s o n t v a l i d e s ( a p r i o r i e l l e s ne l e s o n t p a s ) .




             Enficiaud (INRIA)                                                  C++                                                   16-18/02/2009   81 / 201
 e
H´ritage
Conversions & dynamic cast



Definition (”dynamic cast”)
   e                       e
Op´rateur permettant de d´terminer si une classe est transformable (”       )
                                                                       cast” en
                                      e
une autre en suivant le graphe de l’h´ritage de classe. Dans le cas de pointeurs en
                 e                  e           e                0” e
argument de l’op´rateur, si le cast ´choue, l’op´rateur renvoie ” (z´ro).


1   struct A {};
2   struct B : public A {};
3   B b;
4   A ∗p b = &b ;
5   B ∗p b 2 = d y n a m i c c a s t <B∗>(p b ) ;




                          a     e                  a                  a
Il est possible de tester ` l’ex´cution(et parfois ` la compilation), ` partir d’un
                     ee                                       e
pointeur ou d’une r´f´rence sur une classe, si une classe d´rive ou est une classe
   e
m`re d’une autre.
        e e                                                 e
Plus pr´cis´ment, le compilateur sait si une classe est m`re d’une autre ` laa
                                                          e
compilation, mais l’inverse n’est pas vrai. Le test doit ˆtre fait en runtime.


            Enficiaud (INRIA)                        C++               16-18/02/2009   82 / 201
 e
H´ritage multiple
 e
D´finition




            e
Definition (H´ritage multiple)
   e                                       e
L’h´ritage multiple est lorsqu’une classe h´rite de plusieurs autres classes.

1   struct A {};
2   struct B {};
3   s t r u c t C : p u b l i c A , p u b l i c B { } ; // h ´ r i t e de A e t B
                                                             e


     e     e            e
Les mˆmes r`gles que l’h´ritage simple s’appliquent pour :
                o         e
       Les contrˆles d’acc`s
                   e
       La visibilit´
             e        e
Le graphe d’h´ritage ´tant plus complexe, le compilateur peut se plaindre parfois
                   e                                e                 e
de ne pas pouvoir r´soudre un appel (deux classes m`res ayant une m´thode de
  e               e                           e
mˆme nom/param`tres). Il faut alors faire la d´sambigu¨                e
                                                       ısation de la mˆme
     e               e
mani`re que pour l’h´ritage simple.



            Enficiaud (INRIA)                                              C++       16-18/02/2009   83 / 201
 e
H´ritage multiple
Constructeurs & destructeurs



       e       e               e
De la mˆme mani`re que pour l’h´ritage simple :
                  e
     Les classes m`res sont toutes construites avant n’importe quel attribut
     membre de la classe.
                                       e             e
     Si aucun constructeur de classe m`re n’est appel´ dans la liste d’initialisation,
                          e              e
     le constructeur par d´faut est appel´.
                  e                               a
     Les classes m`res sont construites de gauche ` droite dans la liste des classes
                    e e
     de base (ex. pr´c´dent : A puis B).
et
                  e          e           e
     Les classes m`res sont d´truites apr`s destruction du dernier membre de la
     classe fille
                 e                                                             a
     Elles sont d´truites dans l’ordre inverse de leur construction (de droite `
     gauche dans la liste des classes de base).




        Enficiaud (INRIA)                 C++                           16-18/02/2009   84 / 201
Classes virtuelles
 e
D´finition




                    e
Classe virtuelle - D´finition
                                                        e
Une classe virtuelle est classe contenant au moins une m´thode virtuelle

 e                   e
M´thode virtuelle - D´finition
 e                 e               e         e                     e e
M´thode dont l’impl´mentation peut ˆtre (re)d´finie par une classe d´riv´e.

                                      e
Le mot clef ”virtual ” indique si la m´thode en question est virtuelle (ou pas).
     e                            a              e       e
Une m´thode virtuelle participe ` la taille occup´e en m´moire par la classe.

 e
M´thode virtuelle
     e             e      e                 e
La m´thode appel´e par d´faut (ie. sans sp´cification d’espace de nom) est
                                    e
toujours la plus profonde dans la hi´rarchie des classes.




        Enficiaud (INRIA)                 C++                          16-18/02/2009   85 / 201
Classe virtuelle
Exemple


Classes virtuelles
               e
    Classe A (m`re)                                                                          e
                                                                                  Classe impl´mentation A (fille) - invisible

                                                                                  1                               e
                                                                                       // c l a s s e d ’ i m p l ´ m e n t a t i o n
                                                                                  2    c l a s s A impl : p u b l i c c l a s s A {
                                                                                  3        i n t ∗p ;
    1       class A {                                                             4    public :
    2          std : : s t r i n g s ;                                            5        A impl ( const i n t s i z e = 1000000000000) : A
    3       public :                                                                                 () , p (0) {
    4          A( c o n s t s t d : : s t r i n g &s = " " ) : s ( s ) {}      6               p = new i n t [ s i z e ] ; }
    5          ˜A ( ) {}                                                       7           ˜ A impl () { d e l e t e [ ] p ;}
    6          v i r t u a l void printMe () const {                           8
    7              s t d : : c o u t << " I am A " << s t d : : e n d l ;      9         v i r t u a l void printMe () const {
    8          }                                                              10             s t d : : c o u t << " I am the implementation of
    9       };                                                                                           A " << s t d : : e n d l ;
                                                                              11         }};
                                                                              12       // f a c t o r y
                                                                              13       A∗ f a c t o r y A ( ) { r e t u r n new A i m p l ( ) ; }




Appel
1       A∗ m y c l a s s = f a c t o r y A ( ) ;
2       my class− rintMe ( ) ;
                    >p




                 Enficiaud (INRIA)                                           C++                                                16-18/02/2009    86 / 201
Classes virtuelles
Utilisation



                      e
          Raffinement/sp´cialisation du comportement d’une classe
                  e
          Classe m`re fournit des services minimaux
                                                                    e
          Utilisation d’algorithmes existants avec de nouvelles impl´mentations

            e
 Classe impl´mentation A (fille)
 1   c l a s s A impl : p u b l i c c l a s s A {
 2       i n t ∗p ;
 3   public :
 4       A i m p l ( c o n s t i n t s i z e = 1 0 0 0 0 0 0 0 0 0 0 0 0 ) : A ( ) , p ( 0 ) { p ( new i n t [ s i z e ] ) ; }
 5       ˜ A impl () { d e l e t e [ ] p ;}
 6
 7        v i r t u a l void printMe () const {
 8           A : : printMe () ;
 9            s t d : : c o u t << " I am the implementation of A " << s t d : : e n d l ;
10            s t d : : c o u t << " I print some additional information " << s t d : : e n d l ;
11        }
12   };




              Enficiaud (INRIA)                                                      C++                                          16-18/02/2009   87 / 201
Classes virtuelles pures
 e
D´finition




Definition (Classe virtuelle pure)
                                                             e
Une classe virtuelle pure est classe contenant au moins une m´thode virtuelle pure.

            e
Definition (M´thode virtuelle pure)
 e                         e
M´thode virtuelle sans impl´mentation (ie. = 0)

Syntaxe
1   struct A {
2               e
       // M´ thode v i r t u e l l e p u r e
3      v i r t u a l void printMe () const = 0;
4   };




          Enficiaud (INRIA)                        C++               16-18/02/2009   88 / 201
Classes virtuelles pures
      ee
Propri´t´s




                                  e            e
Une classe virtuelle pure ne peut ˆtre instanci´e

1   struct A {
2      v i r t u a l void printMe () const = 0;
3   };
4   A∗ a = new A ( ) ;                             a                                                 e
                                    // e r r e u r ` l a c o m p i l a t i o n : p r i n t M e non d ´ f i n i t


            e
Une classe m`re peut donc ”               e
                            forcer” l’impl´mentation (dans les classes filles) des
 e                e
m´thodes qu’elle d´clare pures




            Enficiaud (INRIA)                                                 C++                                   16-18/02/2009   89 / 201
Destructeurs
 e
H´ritage
                                     ea                          e
Que se passe-t-il si delete est appel´ ` partir d’une la classe m`re ?

Exemple
            e
    Classe m`re : interface                                                 Classe fille et ”               e           e
                                                                                            factory” : impl´mentation r´elle

                                                                            1    s t r u c t A impl : p u b l i c s t r u c t A {
                                                                            2        A i m p l ( c o n s t i n t s i z e = 1E5 ) : A ( ) , p ( 0 ) {
                                                                                                 p ( new i n t [ s i z e ] ) ; }
                                                                         3           ˜ A impl () { d e l e t e [ ] p ;}
    1       struct A {
                                                                         4           v i r t u a l v o i d d o S o m e t h i n g ( ) {}
    2          std : : s t r i n g s ;
                                                                         5
    3          A( c o n s t s t d : : s t r i n g &s ) : s ( s ) {}
                                                                         6       p r i v a t e : i n t ∗p ;
    4          ˜A ( ) {}
                                                                         7       };
    5          v i r t u a l v o i d doSomething ( ) = 0 ;
                                                                         8
    6       };
                                                                         9
                                                                        10       A∗ f a c t o r y A ( ) {
                                                                        11         r e t u r n new A i m p l ( ) ;
                                                                        12       }




1       A∗ m y c l a s s = f a c t o r y A ( ) ;
2       delete my class ;




Faire l’essai, et proposer une solution.

                 Enficiaud (INRIA)                                     C++                                                      16-18/02/2009      91 / 201
Interfaces
 e
D´finition

Definition (Interface)
     a e
Sert ` d´finir un ”couplage” entre un service (l’objet/composant) et ses clients.

             e e                   e                  e    a
Concept g´n´ral indiquant les m´thodes pour acc´der ` un objet (au moins en
                                  e                  e
exploiter certaines fonctionnalit´s) : l’interface d´finie la signature pour
                                  e                  e
l’utilisation de ces fonctionnalit´s. La particularit´ importante de l’interface est le
  e                    e                           e                              e
d´couplage de l’acc`s d’un objet et de son impl´mentation. Cette particularit´ fait
en sorte que :
   1                                        e            e
       Les clients ne connaissent pas les d´tails d’impl´mentation, et ne sont donc
       pas soumis aux variations de celle-ci (concept objet).
   2                         e                                    e
       L’interface est suppos´e stable en termes de fonctionnalit´s et signatures,
                                a e
       notamment par rapport ` l’´volution d’un composant logiciel.
   3   L’approche par interfaces est souvent moins performante, puisque les
                                                        e                    e
       signatures ne sont pas optimales pour une impl´mentation particuli`re (et que
            e                                                  e              e
       l’acc`s aux variables membres se fait par le biais de m´thodes d’acc`s).
                                               e
En C++, une interface est une classe ne d´finissant aucune variable membre et
                    e
dont toutes les m´thodes sont publiques et virtuelles pures.
        Enficiaud (INRIA)                  C++                          16-18/02/2009   92 / 201
Interfaces
Exemple



                                                     e
 Interface d’une objet permettant d’exploiter des vid´os
 1   class IVideoService {
 2   public :
 3     v i r t u a l bool openVideo ( const s t d : : s t r i n g& f i l e n a m e ) = 0 ;
 4     v i r t u a l bool isOpen () const = 0;
 5     v i r t u a l bool closeVideo ()    = 0;
 6
 7        v i r t u a l bool seekFrame ( long i n t frame number ) = 0 ;
 8        virtual int        g e t F r a m e ( u n s i g n e d c h a r∗ b u f f e r , c o n s t l o n g i n t b u f f e r s i z e , i n t &w i d t h , i n t &h e i g h t ) = 0 ;
 9
10
11        // D e s t r u c t e u r v i r t u e l
12        v i r t u a l ˜ I V i d e o S e r v i c e ( ) {}
13   };




 Rappel
 Ne jamais oublier le destructeur virtuel

  e
 Mˆme s’il s’agit d’un artefact du langage...


                Enficiaud (INRIA)                                                      C++                                                          16-18/02/2009          93 / 201
                         e
                        D´finition & utilisation
                         e
                        D´tails
 Exceptions             Exceptions & constructeurs
        e
structur´es             Exceptions & destructeurs
                        Exceptions standards




     Enficiaud (INRIA)       C++                      16-18/02/2009   94 / 201
                   e
Exceptions structur´es
 e
D´finition


Definition (exception)
                        e           e                e
Une exception est un m´canisme sp´cial du C++, lanc´ par le mot clef ”       ,
                                                                       throw” et
                e        e                                   a
permettant d’arrˆter l’ex´cution courante du programme jusqu’` une instruction
    e e
de r´cup´ration d’exception (bloc ”try” / ”catch”).

L’instruction ”             e
               throw” peut ˆtre suivie de n’importe quelle classe, structure, entier.
                                     e
L’instruction ”catch” intercepte la mˆme classe que celle du ” throw” .

Syntaxe
  D´clarations
   e                                                                         Fonctions levant des exceptions

                                                                             1    // f o n c t i o n s
                                                                             2    void function1 () {
  1    c l a s s Exception1 {};
                                                                             3      s t d : : c o u t << " function1 will throw soon " <<
  2    c l a s s Exception2 : public Exception1 {};
                                                                                                  std : : endl ;
  3    struct Exception3 {
                                                                             4      throw E x c e p t i o n 1 ( ) ;
  4        c o n s t c h a r∗ c o n s t what ;
                                                                             5    }
  5        E x c e p t i o n 3 ( c o n s t c h a r ∗w) : what (w) {}
                                                                             6    void function2 () {
  6    };
                                                                             7      throw f l o a t ( 0 . 3 4 f ) ;
                                                                             8    }




           Enficiaud (INRIA)                                            C++                                           16-18/02/2009    95 / 201
                   e
Exceptions structur´es
Interceptions & relancement


                    ,
Dans le bloc ”catch” throw sans argument relance l’exception au bloc try/catch
   e
sup´rieur.

try/catch
  Interceptions                                                               Relancement

                                                                              1   void function3 () {
                                                                              2     try {
  1    try {
                                                                              3         function1 () ;
  2        function1 () ;
                                                                              4     }
  3    }
                                                                              5     c a t c h ( E x c e p t i o n 1& e ) {
  4    c a t c h ( E x c e p t i o n 1 &e ) {
                                                                              6         s t d : : c o u t << " Caught in f3 : rethrow " <<
  5        s t d : : c o u t << " Caught Ex1 " << s t d : : e n d l ;
                                                                                                    std : : endl ;
  6    }
                                                                           7            throw ;
  7
                                                                           8        }
  8    try {
                                                                           9      }
  9        function2 () ;
                                                                          10
 10    }
                                                                          11      try {
 11    c a t c h ( f l o a t &e ) {
                                                                          12          function3 () ;
 12        s t d : : c o u t << " Caught float Ex " << e << s t d
                                                                          13      }
                        : : endl ;
                                                                          14      c a t c h ( E x c e p t i o n 1 &e ) {
 13    }
                                                                          15          s t d : : c o u t << " Caught Ex1 " << s t d : : e n d l ;
                                                                          16      }




           Enficiaud (INRIA)                                             C++                                                 16-18/02/2009          96 / 201
                   e
Exceptions structur´es
              e e
Interception g´n´rale




                    ,
Dans le bloc ”catch” avec pour argument l’ellipse ( ... ) interceptes toute les
exceptions.

                                              e
Attention : puisque l’exception n’est pas nomm´e, il n’est pas possible d’avoir plus
     e
de pr´cision sur l’exception.

1   try {
2     function3 () ;
3   }
4   catch ( . . . ) {
5     s t d : : c o u t << " Caught some unknown exception " << s t d : : e n d l ;
6   }




Mais : Il est possible de relancer l’exception




           Enficiaud (INRIA)                                        C++                16-18/02/2009   97 / 201
                   e
Exceptions structur´es
 e
D´roulement des interceptions




                                 e
Les intructions ”catch” sont test´es dans l’ordre.


1   try {
2       function3 () ;
3   }
4   c a t c h ( E x c e p t i o n 3 &e ) {
5       s t d : : c o u t << " Caught Ex3 " << s t d : : e n d l ;
6   }
7   c a t c h ( E x c e p t i o n 1 &e ) {
8       s t d : : c o u t << " Caught Ex1 " << s t d : : e n d l ;
9   }




Attention :
    1   a                  e
        ` la gestion de l’h´ritage entre plusieurs exceptions
    2   a
        ` l’ellipse, qui masque toute les autres interceptions




            Enficiaud (INRIA)                                         C++   16-18/02/2009   98 / 201
                   e
Exceptions structur´es
 e                               e
D´roulement des interceptions : d´tails


                                                    e
Voici ce qu’il se passe lorsqu’une exception est lev´e :
   1         e       e
       On arrˆte l’ex´cution du programme au point du ”throw”
   2   Le programme teste s’il se trouve dans un bloc ”try” (si ce n’est pas le cas,
       fin de programme)
   3                                                                        e
       On cherche un bloc ”catch” compatible avec le type de l’exception lev´e (si
       aucun, fin de programme)
   4         e                                                              ,
       On cr´e une sorte de ”tunnel/point de connexion” avec ce bloc ”catch” et on
                                   e e
       se place dans un mode privil´gi´
   5                                                                    e
       Dans ce tunnel, on appelle les destructeurs de tous les objets cr´es sur la pile,
                                      e
       dans l’ordre inverse de leur cr´ation
   6                   e
       On retrouve l’ex´cution du programme au niveau du bloc ”catch”
                                                                    e
On appelle le processus de destruction des objets temporaires : le d´roulement de
pile (stack unwinding ).



         Enficiaud (INRIA)                  C++                           16-18/02/2009   99 / 201
Exceptions
Utilisation

Deux philosophies
    1       Retour de fonction (comme en Java)
    2          e       e
            Arrˆt d’ex´cution sur faute ”        .                                       e
                                           grave” Exemple : on appelle une fonction d´finie
                             e                 e                             e
            par certains crit`res sur les donn´es qu’elle traite, et ces crit`res ne sont pas
                   e
            respect´s.

Performances
Plus d’information sur la pile pour la gestion de l’exception, donc ralentissement
des appels.

    1                 e                                            e
            Possibilit´ de marquer le type d’exception possible lev´e dans une fonction
    2                                     a u
            Rapprochement du catch de l` o` l’exception est potentiellement lev´ee
    3                                                                e
            Utilisation d’un mot clef pour indiquer qu’un appel ne l`ve pas d’exception ou
                e                                                      e
            ne l`ve une exception que d’un certain type (non support´ par tous les
            compilateurs).
1       v o i d f u n c t i o n 1 ( ) throw ( ) ;
2       v o i d f u n c t i o n 2 ( ) throw ( E x c e p t i o n 3 ) ;
3       v o i d f u n c t i o n 2 ( ) throw ( . . . ) ;


                 Enficiaud (INRIA)                                       C++   16-18/02/2009   100 / 201
Exceptions
Cohabitation avec les constructeurs


                            e
Les exceptions cohabitent tr`s bien avec les constructeurs !

                                                           e
En effet, les constructeurs n’ont pas de valeur de retour (r´sultat = objet
                                                                    e
construit). Lever une exception dans le constructeur en cas de probl`me permet :
  1                                e                                             ee
      Lorsqu’une exception est lev´e dans le constructeur, la classe n’est pas cr´´e.
  2                                                   e            e
      Les destructeurs des variables membres initialis´s sont appel´s
  3                                                                       e
      Le destructeur de la classe en cours de construction n’est pas appel´ (la
                     ee
      classe n’a pas ´t´ construite).
  4                                  e           e             e
      Les destructeurs des classes m`res instanci´es sont appel´es (l’ordre
                               o
      d’instanciation joue un rˆle important).




        Enficiaud (INRIA)                 C++                          16-18/02/2009   101 / 201
Exceptions
Cohabitation avec les destructeurs

                                   e e
 Rappel : (quelques diapositives pr´c´dentes) le processus de stack unwinding est
   e e
 ex´cut´ dans un mode particulier.
                               e
 En fait, ce mode est particuli`rement fragile, et ne supporte absolument pas un
 lancement d’exception.

 Donc ...
 Il NE FAUT PAS lever une exception dans le destructeur

 Qu’avons-nous avec l’exemple ci-dessous ?
 1   class A {
 2      ˜A ( ) {
 3                                     e
            // e x c e p t i o n l e v ´ e d a n s l e d e s t r u c t e u r de A .
 4          throw s t d : : r u n t i m e e x c e p t i o n ( " some error " ) ;
 5      }
 6   };
 7   try {
 8      A a;
 9      throw s t d : : r u n t i m e e x c e p t i o n ( " juste pour embeter " ) ;
10   } catch ( . . . ) {
11      s t d : : c o u t << " C ’ est bon , je recupere " << s t d : : e n d l ;
12   }




             Enficiaud (INRIA)                                                C++       16-18/02/2009   102 / 201
Exceptions
Standard ”STL”




Le standard (fichier ”                              e
                      <stdexcept>” de la STL) d´fini quelques exceptions ”type”.
                                        ,        e           e
La classe de base est ”std :: exception” qui impl´mente la m´thode
”virtual const char ∗ std :: exception :: what() const” donnant des
                                                       ,
renseignements ”utilisateurs” sur le message de l’exception.
1   std   ::                                                                 a           e
            r u n t i m e e r r o r ; // r e p o r t e l e s e r r e u r s ` l ’ e x ´ c u t i o n
2   std   ::l o g i c e r r o r ; // r e p o r t e l e s e r r e u r s de l o g i q u e d ’ a p p e l
3   std   ::i n v a l i d a r g u m e n t ; // a rg um e nt i n v a l i d e d ’ un a p p e l
4   std   ::out or range ;                                       e                                   e
                                        // r e p o r t e l e s d´ p a s s e m e n t s : u t i l i s ´ d a n s c e r t a i n s a p p e l s STL ( s u b s t r i n g , v e c t o r
               ...)
5   std : : bad alloc ;                                              e                                 e
                                    // r e p o r t e l e s p r o b l ` m e s d ’ a l l o c a t i o n m´ moire ( d a n s h e a d e r <new>)


         e e                     a                            ıtre
Il faut g´n´ralement se reporter ` la documentation pour connaˆ les exceptions
             e e
qu’on doit r´cup´rer. Les exceptions font partie du comportement du service
         e
demand´ : elles affectent le fonctionnement de VOTRE programme.




               Enficiaud (INRIA)                                                       C++                                                          16-18/02/2009            103 / 201
Exceptions
Exercice

But
                                                                        `
Soit une classe ”ContenuFichier” qui contient le contenu d’un fichier. A son
instanciation, il ouvre le fichier, lit son contenu et le met dans un buffer, puis
ferme le fichier.
                         a
      Il ouvre le fichier ` l’aide de la fonction ”fopen”.
                                                                        .
      Si le fichier n’existe pas, il lance une exception ”file not found ” Cette
                     a e                                                   e
      exception est ` d´finir. Elle doit contenir le nom du fichier recherch´.
      Si le fichier existe, le constructeur alloue une zone m´moire de type ”char ∗”
                                                              e
                                                                            a
      d’une taille de 1024 octet (1Ko). Il lit ensuite le contenu du fichier ` l’aide de
      la fonction C ”fread” (”#include <cstdio>”    ).
                               e                                          e e
      tant qu’il n’a pas termin´ la lecture du fichier, il place le bloc pr´c´demment
         a
      lu ` la fin d’un tableau. Pour cela, on utilisera un vecteur STL ”std :: vector”
      (”                               e
        #include <vector>”) et sa m´thode ”std :: vector :: push back”    .
      a                                                 e
      ` la fin de lecture, il doit allouer un gros bloc m´moire, dans lequel il va
                         e e                      e       e
      copier les blocs pr´c´demment lus et plac´s en m´moire.

           Enficiaud (INRIA)                C++                         16-18/02/2009   104 / 201
Exceptions
Exercice (suite)




         e      e
Il doit g´rer tr`s proprement
               e
      les probl`mes de lecture
               e                  e
      les probl`mes d’allocation m´moire (”std :: bad alloc ”)
      la fermeture du fichier (toujours)
            e                       e             e
      la lib´ration des ressources m´moires interm´diaires
      le lancement d’exceptions suffisamment informatives




         Enficiaud (INRIA)                 C++                    16-18/02/2009   105 / 201
Etude de cas




    Enficiaud (INRIA)   C++   16-18/02/2009   106 / 201
Etude de cas
   ıne
Chaˆ algorithmique
                                                      a       ıne a
On veut un programme qui applique des algorithmes ` la chaˆ ` une structure
        e                               a                        a
de donn´e initiale. Chaque algorithme ` une interface identique ` tous les autres
                            e             ıne
algorithmes. Il sera identifi´ dans la chaˆ par son nom. Pour chaque chaˆ  ıne
                                    a                                    A”
algorithmique, chaque algorithme ` un nom unique. Chaque algorithme ” peut
  e                      e              e        e             ıne
cr´er une nouvelle donn´e, qui pourra ˆtre utilis´e dans la chaˆ par les
                                      e                         e
algorithmes en aval de ”A”. La donn´e sera par exemple identifi´e par son type
                                            ee
exact et le nom de l’algorithme qui l’a cr´´.
L’exercice est en deux phases :
  1              e        e               a            e             e
      Phase de r´flexion/´tude/design : ` l’aide de m´canismes d’h´ritage et
                     e
      d’interfaces, d´finissez les intervenants informatiques. On fera un point sur le
      design.
  2             e
      Phase de d´veloppement : vous retroussez vos manches.
     e
En 4 ´quipes.
  1    e
      D´finition de l’interface d’un algorithme
  2    e                                e
      D´finition de la structure de donn´e
  3     e
      Cr´ation de deux algorithmes

        Enficiaud (INRIA)                 C++                          16-18/02/2009   107 / 201
                                      e
                   Formation C++ avanc´e



                                       e e
                   J2 : Programmation g´n´rique




Enficiaud (INRIA)               C++                16-18/02/2009   108 / 201
                    e e
J2 : Programmation g´n´rique
Contenu




7   Les templates

8   STL

9   Patrons de conception (Design patterns)




          Enficiaud (INRIA)             C++    16-18/02/2009   109 / 201
                       Introduction
                          e
                       Pr´sentation
                         e
                       M´canismes
                           e             e
                         D´claration & d´finition
Les templates            Espace de nom
                            e
                         Inf´rence de type
                            e
                         Sp´cialisation
                                            e
                         Programmation incr´mentale
                            e
                       Synth`se




    Enficiaud (INRIA)         C++                      16-18/02/2009   110 / 201
Template
                    e
Introduction : probl`me de redondance algorithmique


   e
Lab´lisation

                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                          e
                                                          D´veloppements
                                                               e
                                                         trop sp´cifiques `a
                           Mesures du nombre
                                                     
                                                     
                                                         une application !
                            de composantes           
                                                     
                                                     




        Enficiaud (INRIA)                       C++                       16-18/02/2009   111 / 201
Template
                    e
Introduction : probl`me de redondance algorithmique


   e
Lab´lisation

                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                        
                                                                    e
                                                                    D´veloppements
                                                                         e
                                                                   trop sp´cifiques `a
                           Mesures du nombre
                                                        
                                                        
                                                                   une application !
                            de composantes              
                                                        
                                                        



      e
Sans m´ta-programmation
                                               Mesures du nombre               Mesures de surface
                                                de composantes                  des composantes

                                                                                                    ······


        Enficiaud (INRIA)                        C++                                    16-18/02/2009   111 / 201
Template
                    e
Introduction : probl`me de redondance algorithmique




      e
Avec m´ta-programmation




                            Méta-programme            Mesures du nombre
                                                       de composantes

                                                      Mesures de surface
                                                       des composantes




        Enficiaud (INRIA)                     C++                     16-18/02/2009   112 / 201
Templates
               e patrons”
Egalement appel´s ”


Definition (Template)
                             e
Les templates permettent de d´finir des familles de classes, structures ou fonctions.

      e          e
     M´canisme tr`s puissant !
       1                            a                      e          e e
           permet de rapidement (` partir d’un code compl`tement typ´) d´finir une
           famille de classe ou de fonction
       2                           e
           permet d’ajouter des m´canismes logiques dans le choix des
                                       e    e
           structures/fonctions invoqu´es (m´ta-programmation)
       3                                                a
           permet d’avoir un code facilement extensible ` des nouveaux cas d’utilisation
             a
     Difficile ` prendre en main
     Certains compilateurs sont en retard dans le support des templates (il faut les
     bannir)




       Enficiaud (INRIA)                    C++                           16-18/02/2009   113 / 201
Templates
  e
Pr´sentation

                                    e e
 Les familles en question sont param´tr´es par des types :
                                               e
         Ces types restent abstraits lors de l’´criture du template en question
                                                                        a
         Il deviennent concrets lors de l’utilisation de ces templates (` la compilation)
                     e
 Il est possible de d´finir des templates :
     1   sur des structures ou des classes
     2   sur des fonctions

 1   // S t r u c t u r e t e m p l a t e , a v e c 3 a r g u m e n t s :
 2   // − deux c l a s s e s I e t U ,
 3   // − un b o o l ´ e n p a r d ´ f a u t ` t r u e
                         e                e        a
 4   t e m p l a t e <typename I , c l a s s U , b o o l B = t r u e >
 5       struct s structure {
 6       /∗ . . . ∗/
 7   };
 8
 9   // F o n c t i o n t e m p l a t e , a v e c 3 a r g u m e n t s
10   // − un a rg umen t e x p l i c i t e b o o l ´ e n B   e
11   // − deux a r g u m e n t s i m p l i c i t e s de t y p e U e t V ( i n d ´ f i n i s )
                                                                                e
12   t e m p l a t e <b o o l B , c l a s s U , c l a s s V>
13       b o o l f u n c t i o n t e m p l a t e ( c o n s t U&, V) {
14       /∗ . . . ∗/
15   }




             Enficiaud (INRIA)                                                   C++             16-18/02/2009   114 / 201
Templates
Exemple




Un exemple trivial de l’abstraction du type pour des fonctions...

Transformation
                                                                              e                           e     T”      e
                                                                            M´ta algorithme (int transform´ en ” et tagg´ comme argument
                e
  Algorithme typ´
                                                                            template)

                                                                            1   t e m p l a t e < c l a s s T>
 1    i n t maximum ( c o n s t i n t i 1 , c o n s t i n t i 2 ) {         2       T maximum (T i 1 , T i 2 )
 2        return i1 > i2 ? i1 : i2 ;                                        3   {
 3    }                                                                     4       return i1 > i2 ? i1 : i2 ;
                                                                            5   }




           Enficiaud (INRIA)                                           C++                                           16-18/02/2009      115 / 201
Templates
Exemple & remarque




                                                         T”
La fonction maximum sera alors appelable pour tout type ” , MAIS avec les
conditions suivantes :
   1                                   e        >”
        l’algorithme est valide si l’op´rateur ” existe pour le type ”T”
   2    la fonction prend des copies des objets et retourne une copie, ce qui n’est pas
        valide pour tout type ”T” :
            1        e
                 l’op´rateur par recopie est correct pour l’algorithme (il retient l’information
                 permettant de faire la comparaison)
            2        e
                 l’op´rateur par recopie est correct pour la partie appelante (”return” ne
                                    ee
                 retourne pas une r´f´rence, mais une copie temporaire)
            a                               e                      e
On commence ` comprendre pourquoi c’est si s´duisant, mais un peu d´licat ?




            Enficiaud (INRIA)                                           C++        16-18/02/2009   116 / 201
Templates
Exemple (2)



Un exemple trivial de l’abstraction du type pour des structures...

Transformation
               e
  Structure typ´e                                                     e
                                                                     M´ta structure

                                                                  1       template <
                                                                  2         class storage type ,
  1    struct s my struct {                                       3         i n t s i z e = 10 ,
  2      int value1 [ 1 0 ] ;                                     4         class return type = float >
  3      typedef f l o a t return type ;                          5       struct s my struct t {
  4                                                               6         storage type value1 [ s i z e ] ;
  5         return type operator () () {                          7         typedef re tu rn t yp e return type ;
  6           int ret = 0;                                        8
  7           f o r ( i n t i = 0 ; i < 1 0 ; i ++) r e t +=      9            return type operator () () {
                           value1 [ i ] ;                        10              storage type ret = 0;
  8           return ret / 10. f ;                               11              f o r ( i n t i = 0 ; i < s i z e ; i ++)
  9         }                                                    12                  r e t += v a l u e 1 [ i ] ;
 10    };                                                        13              return ret / size ;
                                                                 14            }
                                                                 15       };




             Enficiaud (INRIA)                                  C++                                               16-18/02/2009   117 / 201
Templates
 e
D´tails




                     e
Il existe plusieurs m´canismes autour de l’utilisation des templates :
   1       e                 e
       la d´claration et la d´finition
   2        e
       la sp´cialisation totale ou partielle
   3       e            e
       la d´duction (inf´rence) de type pour les fonctions templates




          Enficiaud (INRIA)                     C++                     16-18/02/2009   118 / 201
Templates
 e             e
D´claration & d´finition
    e
La d´claration commence par le mot clef ”         ,
                                         template” suivi de :
    1       ”<” une liste de types ”>”
    2       ”class ” ou ”struct ” pour les classes et structures, ou un type de retour pour
            les fonctions templates
    3       le nom de la fonction ou de la structure/classe
    4                                                              e
            les arguments pour une fonction template (entre parenth`ses)
    5                           e
            optionnellement la d´finition du corps
    6       et enfin ”;” (point de terminaison)

 e
D´claration
1       t e m p l a t e < c l a s s T> s t r u c t s t e m p l a t e t ; // s t r u c t u r e t e m p l a t e
2       t e m p l a t e < c l a s s T> T f u n c ( i n t , T) ;        // f o n c t i o n t e m p l a t e




      e
Les d´clarations, classiquement, indiquent au compilateur que ces fonctions et ces
structures templates existent.
                e
Elles indiquent ´galement le nombre d’arguments abstraits dans le template (utile
           e
pour la sp´cialisation ou pour les arguments templates).
                 Enficiaud (INRIA)                                                       C++                     16-18/02/2009   119 / 201
Templates
Liste des types admissibles


Les types admissibles dans la liste des type sont :
       des types ”abstraits” : ”class ” ou ”typename” suivi de leur nom
       des valeurs constantes connues au moment de la compilation, et du type :
                                ee
       entier, enum, pointeur, r´f´rence ou pointeur sur membre (le pointeur inclut
                                       e
       son naturellement le type point´)
       des classes templates
Il est possible d’avoir, pour les classes et structures templates, des arguments
                 e                        ee a                e e
templates par d´faut (et qui peuvent r´f´rer ` des types pr´c´dents)
1   t e m p l a t e < c l a s s T , c l a s s U = i n t , c l a s s V = T>
2       struct s struct ;
3
4          e
    // mˆme p r i n c i p e que p o u r l a s u r c h a r g e , V non o p t i o n n e l ne p e u t s u i v r e un a rg u me nt o p t i o n n e l
5   t e m p l a t e < c l a s s T , c l a s s U = i n t , c l a s s V>
6       struct s struct2 ;
7
8   template <c l a s s T, c l a s s U = int >
9     T f u n c 1 (T , U) ;                                 e
                            // i n t e r d i t ! p a s de d ´ f a u t s u r l e s     fonctions templates




            Enficiaud (INRIA)                                                  C++                                                    16-18/02/2009   120 / 201
Templates
Liste des types admissibles : valeurs




 1                                                            e
     // r a p p e l : ” s t a t i c c o n s t i n t ” e s t d ´ f i n i s s a b l e d a n s l e c o r p s de l a c l a s s e
 2   template <i n t I> s t r u c t s t e m p l a t e t 1 {
 3      s t a t i c const i n t i = I ;
 4      i n t j , k , l , m, o ;
 5   };
 6
 7   s t e m p l a t e t 1 <20>      o1 ;         // ok
 8
 9   t e m p l a t e <b o o l B> s t r u c t s t e m p l a t e t 2 ;
10   s t e m p l a t e t 2 <t r u e > o2 ;       // ok
11
12   bool b = f a l s e ;
13   s t e m p l a t e t 2 <b>    o3 ;         // e r r e u r : b v a r i a b l e ( i n c o n n u au moment de l a c o m p i l a t i o n )
14
15   c o n s t b o o l bc = f a l s e ;
16   s t e m p l a t e t 2 <bc>     o4 ;          // ok : bc c o n s t a n t
17
18   s t e m p l a t e t 1 <bc>      o5 ;                                               e a               e         e a
                                                  // ok : b o o l ” t r u e ” e v a l u ´ ` 1 , f a l s e ´ v a l u ´ ` 0
19
20   enum e v a l { v a l 1 , v a l 2 = 2 } ;
21   t e m p l a t e < e v a l E> s t r u c t s t e m p l a t e t 3 ;
22   s t e m p l a t e t 3 <v a l 2 > o6 ;      // ok
23   s t e m p l a t e t 3 <2> o7 ;           // e r r e u r : e n t i e r n ’ e s t p a s enum !




              Enficiaud (INRIA)                                                      C++                                                  16-18/02/2009   121 / 201
Templates
Liste des types admissibles : valeurs (2)
 Suite...

 1
 2   t e m p l a t e < f l o a t F> s t r u c t s t e m p l a t e t 4 ; // e r r e u r :    float     interdit
 3
 4   s t a t i c c h a r ∗ c o n s t c h a i n e = " blablabla " ;
 5   t e m p l a t e <c h a i n e > s t r u c t s t e m p l a t e t 5 ;
 6
 7   // t e m p l a t e a v e c a rg ume n t un p o i n t e u r s u r f o n c t i o n ( r e t o u r n a n t
 8                                     e
     // v o i d e t s a n s p a r a m ` t r e s )
 9   t e m p l a t e <v o i d (∗U) ( )> s t r u c t s t e m p l a t e t 6 ;
10
11   void func1 () ;
12   s t e m p l a t e t 6 <&f u n c 1 > o8 ; // ok
13   s t e m p l a t e t 6 <f u n c 1 > o9 ; // e r r e u r :    il                         e e
                                                                      f a u d r a i t une r ´ f ´ r e n c e
14
15   t e m p l a t e < i n t I , i n t s t e m p l a t e t 1 <I >::∗ J> s t r u c t s t e m p l a t e t 7 {
16       s t e m p l a t e t 7 ( ) : v a l u e p ( J ) {}
17       i n t s t e m p l a t e t 1 <I >::∗ v a l u e p ; // p o i n t e u r m u t a b l e
18       s t a t i c c o n s t i n t s t e m p l a t e t 1 <I >::∗ v a l u e p s ;
19   };
20   t e m p l a t e < i n t I , i n t s t e m p l a t e t 1 <I >::∗ J>
21   c o n s t i n t s t e m p l a t e t 1 <I >::∗ s t e m p l a t e t 7 <I , J > : : v a l u e p s = J ;
22
23   s t e m p l a t e t 1 <10> op ;
24   op . i = op . j = 2 0 ;
25   op . k = op . l = 3 0 ;
26
27   t y p e d e f s t e m p l a t e t 7 <10 , &s t e m p l a t e t 1 <10 >:: l > o p 2 t ;
28   o p 2 t op2 ;
29   s t d : : c o u t << op .∗ op2 . v a l u e p << s t d : : e n d l ;
30   s t d : : c o u t << op .∗ op2 . v a l u e p s << s t d : : e n d l ;
31   s t d : : c o u t << op .∗ o p 2 t : : v a l u e p s << s t d : : e n d l ;



              Enficiaud (INRIA)                                                        C++                        16-18/02/2009   122 / 201
Templates
Liste des types admissibles : template

        e
 Il est ´galement possible de mettre parmi les arguments, un autre template. Il doit
 e      e e e e                    e                          e         e
 ˆtre d´clar´ pr´cis´ment avec la mˆme liste template que sa d´finition/d´claration.

 1          e
     // d ´ c l a r a t i o n de s t e m p l a t e 1 , s t e m p l a t e 2 , s t e m p l a t e 3
 2   template <c l a s s A, i n t I>
 3     s t r u c t s t e m p l a t e 1 {/∗ . . . ∗/ } ;
 4
 5   template <c l a s s A, i n t I>
 6     struct s template2 ;
 7
 8   t e m p l a t e < c l a s s A , c l a s s B , c l a s s C>
 9       s t r u c t s t e m p l a t e 3 {/∗ . . . ∗/ } ;
10
11          e
     // d ´ c l a r a t i o n de s t e m p l a t e 4 a c c e p t a n t un t e m p l a t e en a rg um e nt
12   // c e t a rg ume n t t e m p l a t e (A) a deux a r g u m e n t s t e m p l a t e : c l a s s e t i n t
13   t e m p l a t e <t e m p l a t e < c l a s s A1 , i n t I 1 > c l a s s A>
14       struct s template4
15   {
16       A<i n t , 10> o p i n t ;
17       A<f l o a t , 40> o p f l o a t ;
18       // . . .
19   };
20
21   s t e m p l a t e 4 <s t e m p l a t e 1 > op1 ; // ok
22   s t e m p l a t e 4 <s t e m p l a t e 2 > op2 ; // non ok ! l e c o r p s de s t e m p l a t e 2 n ’ e s t p a s connu
23   s t e m p l a t e 4 <s t e m p l a t e 3 > op3 ; // e r r e u r s u r l a m i s e en c o r r e s p o n d a n c e d e s a r g u m e n t s




              Enficiaud (INRIA)                                                       C++                                                        16-18/02/2009   123 / 201
Templates
Espace de noms & champs de type
           e                                                   e
Un peu le mˆme principe que les namespace : utilisation de l’op´rateur :: .

Definition (”types complets”)
Dans un template, les types complets sont les types connus :
     soit parce que ce ne sont pas des types abstraits (constantes)
     soit parce qu’ils font partie de la liste d’arguments template a
                                   e
   a. les arguments templates sont ´galement des types


Definition (”      e
            noms d´pendants”)
         e                                                ıtre
Un nom d´pendant est un type qu’il n’est possible de connaˆ qu’une fois le type
              e        e
template compl`tement r´solu.

 e
R`gle
             e                    e       e e    e                 .
Les noms d´pendants doivent ˆtre acc´d´s via l’op´rateur ”typename” Ce mot clef
                                        e
indique au compilateur que le nom d´pendant est un type.
                   a      e
Il n’est valide qu’` l’int´rieur des templates.
        Enficiaud (INRIA)                     C++                        16-18/02/2009   124 / 201
Templates
Espace de noms & champs de type (2)




 Syntaxe
 1   t e m p l a t e < c l a s s T , c l a s s U>
 2   struct A {
 3       T t;
 4       U u;
 5       t y p e d e f typename T : : r e t u r n t y p e r e t u r n t y p e ; // champ membre de t y p e T : : r e t u r n t y p e
 6
 7        A( c o n s t U&u    = U ( ) ) : t ( ) , u ( u ) {}
 8
 9        r e t u r n t y p e operator () () const {
10            typename U : : c o n s t i t e r a t o r // v a r i a b l e s l o c a l e s de t y p e U : : i t e r a t o r t y p e
11                i t = u . begin () ,
12                i t e = u . end ( ) ;
13            return t ( it , i t e ) ;            // T : : o p e r a t o r ( )
14        }
15   };




               Enficiaud (INRIA)                                                     C++                                                16-18/02/2009   125 / 201
Templates
Exercice 1




  1                     e
      S’abstraire des op´rations de recopies dans le template suivant :
      1   t e m p l a t e < c l a s s T>
      2       T maximum ( c o n s t T i 1 , c o n s t T i 2 )
      3   {
      4       return i1 > i2 ? i1 : i2 ;
      5   }


  2                                                             e
      En faire un functor, qui sache renseigner ses types d’entr´e et de sortie.




          Enficiaud (INRIA)                                      C++   16-18/02/2009   126 / 201
Templates
Exercice 2




                                                      e
 Ecrire une structure template give me square, pr´sentant une interface de tableau
      e                                      e        e
 indic´ ”operator [] ”, et retournant le carr´ de l’op´rateur de fonction template
 (”functor” - ”operator ()”) suivant :
 1    template <
 2      class storage type ,
 3      i n t s i z e = 10 ,
 4      class return type = float >
 5    struct s my struct t {
 6      storage type value1 [ s i z e ] ;
 7      typedef re tu rn t yp e return type ;
 8
 9         return type operator () () {
10           storage type ret = 0;
11           f o r ( i n t i = 0 ; i < s i z e ; i ++)
12               r e t += v a l u e 1 [ i ] ;
13           return ret / size ;
14         }
15    };

 Ce mini exercice doit montrer comment interfacer correctement deux templates.




               Enficiaud (INRIA)                                          C++     16-18/02/2009   127 / 201
Templates
Exercice 3
 1   t e m p l a t e < c l a s s T , c l a s s U>
 2   struct A {
 3       T t;
 4       U u;
 5       t y p e d e f typename T : : r e t u r n t y p e r e t u r n t y p e ; // champ membre de t y p e T : : r e t u r n t y p e
 6
 7        A( c o n s t U&u    = U ( ) ) : t ( ) , u ( u ) {}
 8
 9        r e t u r n t y p e operator () () const {
10            typename U : : c o n s t i t e r a t o r // v a r i a b l e s l o c a l e s de t y p e U : : i t e r a t o r t y p e
11                i t = u . begin () ,
12                i t e = u . end ( ) ;
13            return t ( it , i t e ) ;            // T : : o p e r a t o r ( )
14        }
15   };




 Exercice
                     T”              U”
 Ecrire des classes ” et une classe ” qui soient compatibles avec la structure
                                                                 U”
 template ”A” ci-dessus. On pourra prendre par exemple pour ” : une classe cr´´e    ee
 par vos propres soins (si vous avancez vite), ou ”std :: vector” (facile) ou encore
 ”std :: map” (un peu moins facile).

 Exercice
                                              A”
 Ecrire une fonction cliente de la structure ” de test.
               Enficiaud (INRIA)                                                     C++                                                16-18/02/2009   128 / 201
Templates
Intanciation/appel explicite


Definition (appel explicite)
             e                             e
Le fait de sp´cifier tous les types est nomm´ l’appel explicite

Exemple pour une classe
1   t e m p l a t e < c l a s s T> s t r u c t A {/∗ . . . ∗/ } ;
2   A<b o o l > op ;




Exemple pour une fonction
1   t e m p l a t e < c l a s s T>
2       b o o l f u n c t i o n t ( c o n s t T& t ) {/∗ . . . ∗/}
3
4   bool b = f a l s e ;
5   b = f u n c t i o n t <b o o l >(b ) ;
6
7   t y p e d e f s t d : : v e c t o r <i n t > v e c t i n t ;
8   vect int val ;
9   b = f u n c t i o n t <v e c t i n t >( v a l ) ;




              Enficiaud (INRIA)                                       C++   16-18/02/2009   129 / 201
Templates
   e
Inf´rence de types


             inf´
 Definition (” erence de types”)
      e           e                       e          oe
 La d´duction/inf´rence des types est un m´canisme cˆt´ compilateur permettant
      e                                     e
 de d´couvrir automatiquement les types (inf´rence) en fonction des arguments de
 l’appel d’une fonction template.

 Exemple
 1   t e m p l a t e < c l a s s T , c l a s s U>
 2   b o o l m y f u n c t i o n ( c l a s s T& t , c l a s s U& u ) {
 3
 4       typename T : : r e t u r n t y p e r e t u r n v a l u e ;         // v a r i a b l e de t y p e ”champ membre T : : r e t u r n t y p e ”
 5
 6       typename U : : c o n s t i t e r a t o r                 // v a r i a b l e s   l o c a l e s de t y p e ”U : : i t e r a t o r t y p e ”
 7               i t = u . begin () ,
 8               i t e = u . end ( ) ;
 9       f o r ( ; i t != i t e ; ++i t ) {
10           r e t u r n v a l u e += t (∗ i t ) ;            // T : : o p e r a t o r ( )
11       }
12
13       return r e t u r n v a l u e > 1000;                                                                                e
                                                                  // e x e m p l e de t r a n s f o r m a t i o n en b o o l ´ e n
14   }




              Enficiaud (INRIA)                                                      C++                                                          16-18/02/2009   130 / 201
Templates
   e
Inf´rence de types (2)

                                e                                           e
Il est possible d’utiliser l’inf´rence de type uniquement sur les types pass´s en
                              e      e
argument de l’appel. L’inf´rence ´choue donc
                                               e     e
        si certains types templates ne peuvent ˆtre d´duits de l’appel
        si certains types templates concernent les types de retour des fonctions
        templates

Exemple 1 (qui ne fonctionne pas)
1   t e m p l a t e < c l a s s T , c l a s s U>
2   b o o l m y f u n c t i o n ( c o n s t T& t , c o n s t T& u ) {
3       // . . .
4   }




Exemple 2 (qui ne fonctionne pas)
1   t e m p l a t e < c l a s s T , c l a s s U>
2   U m y f u n c t i o n ( c o n s t T& t , c o n s t T& u ) {
3       // . . .
4   }



            Enficiaud (INRIA)                                            C++   16-18/02/2009   131 / 201
Templates
   e
Inf´rence de types : exercice




     e
Enonc´
                                  e                                   e
Ecrire une fonction template qui ´crit dans ”std :: cout” le type pass´ en argument
                      e
(la valeur ne nous int´resse pas ici). On se servira le mot clef C++ ”typeid (T)” et
     e                                 e
la m´thode ”name” de l’objet retourn´ ”typeid (T).name()”    .

Attention : ”typeid”
                                       e                       e               e     e
La sortie de ”typeid” est compilateur d´pendant ! Il est utilis´ pour tester l’´galit´
                                              e
de types, mais non pour une sortie textuelle v´ritablement informative. ”typeid”
retourne un objet CONSTANT ”type info ” (inclure le fichier
#include <typeinfo>).




         Enficiaud (INRIA)                 C++                          16-18/02/2009   132 / 201
Templates
  e
Sp´cialisation



              e
 Definition (Sp´cialisation)
      e                                                            e
 La sp´cialisation permet d’indiquer que, pour un template donn´, et pour une
                      e
 combinaison particuli`re de ses types, il existe une nouvelle version de ce template.

 Syntaxe
 1   t e m p l a t e < c l a s s T , c l a s s U>
 2   struct s my template                              e
                                                  // d ´ c l a r a t i o n de s m y t e m p l a t e
 3   {
 4       typedef T r e s u l t t y p e ;
 5   };
 6
 7   t e m p l a t e <>
 8   s t r u c t s m y t e m p l a t e <i n t , i n t >                e
                                                              // s p ´ c i a l i s a t i o n de s m y t e m p l a t e p o u r l a c o m b i n a i s o n i n t , i n t
 9   {
10                                                                                                                   e                                  e
         t y p e d e f s m y t e m p l a t e <i n t , i n t > s e l f t y p e ; // l e c o n t e n u de l a s p ´ c i a l i s a t i o n e s t c o m p l` t e m e n t
                          e
                      diff´rent
11   };
12
13   s m y t e m p l a t e <f l o a t , b o o l > op ;                 e
                                                         // p r e m i ` r e v e r s i o n
14   s m y t e m p l a t e <i n t , i n t > op2 ;                  e
                                                       // d e u x i` m e v e r s i o n




              Enficiaud (INRIA)                                                       C++                                                         16-18/02/2009          133 / 201
Templates
  e
Sp´cialisation totale/partielle

Notion FONDAMENTALE !
      e                    e                       e
La sp´cialisation est un m´canisme puissant qui rel`gue au compilateur les choix
                           e                  e
des structures lors de la d´couverte des param`tres templates.

Notion FONDAMENTALE ! (bis)
     e             e
La sp´cialisation d´finit des NOUVEAUX TYPES. Une classe template et ses
sp´cialisations n’ont RIEN DE COMMUN a .
  e
   a. en termes de contenu

               e e                     s
Cf. exemples pr´c´dents : les classes ” my template<U,V>” et
” s my template<int, int >” sont des TYPES DIFFERENTS.

             e
Definition (Sp´cialisation totale)
                   e             u                                       e
C’est un type de sp´cialisation o` tous les types templates sont renseign´s.

               e e
Cf. exemples pr´c´dents.
         Enficiaud (INRIA)               C++                         16-18/02/2009   134 / 201
Templates
  e
Sp´cialisation totale/partielle



              e
 Definition (Sp´cialisation partielle)
                    e             u                        a
 C’est un type de sp´cialisation o` certains types restent ` renseigner.

 Syntaxe
 1   t e m p l a t e < c l a s s T , c l a s s U>
 2   struct s my template                              e
                                                  // d ´ c l a r a t i o n de s m y t e m p l a t e
 3   {
 4       typedef T r e s u l t t y p e ;
 5   };
 6
 7   t e m p l a t e <typename U>
 8   s t r u c t s m y t e m p l a t e <i n t , U>                e
                                                         // s p ´ c i a l i s a t i o n de s m y t e m p l a t e p o u r l a c o m b i n a i s o n i n t , U
 9   {
10       t y p e d e f s m y t e m p l a t e <i n t , U> s e l f t y p e ;
11   };
12
13   s m y t e m p l a t e <f l o a t , b o o l > op ;                 e
                                                         // p r e m i ` r e v e r s i o n
14   s m y t e m p l a t e <i n t , i n t > op2 ;                  e
                                                       // d e u x i` m e v e r s i o n




              Enficiaud (INRIA)                                                       C++                                                      16-18/02/2009    135 / 201
Templates
  e
Sp´cialisation totale/partielle : exercice

      e
 Enonc´
              e                                                                    e
 Ecrire une sp´cialisation de la structure de copie suivante, lorsqu’elle est appel´e
                                                   e    T”
 avec deux pointeurs constants sur entier (param`tre ” ) et un pointeur sur double
        e
 (param`tre ” U”).

           a e
 Structure ` sp´cialiser
 1   t e m p l a t e < c l a s s T , c l a s s U>
 2   s t r u c t Copy {
 3       v o i d o p e r a t o r ( ) (T i t 1 , T i t 2 , U i t o u t )
 4       {
 5           f o r ( ; i t 1 != i t 2 ; ++i t 1 , ++i t o u t )
 6           {
 7              ∗i t o u t = ∗i t 1 ;
 8           }
 9       }
10   };




      e
 Enonc´
              e                      e                                   e
 Ecrire une sp´cialisation de cette mˆme structure, lorsqu’elle est appel´e avec des
                e
 pointeurs de mˆme type (entier par exemple).
              Enficiaud (INRIA)                                            C++   16-18/02/2009   136 / 201
Templates
  e                                e
Sp´cialisation & programmation incr´mentale



     Supposons que nous avons un functor ”s do very weird things ” qui travaille
                               T
     sur un ensemble de types ” i ”
                                                       am´ e
     Supposons que maintenant, nous avons une version ” elior´e” de ce functor,
     pour une combinaison C de ces types
                                                am´ e
Alors, il est possible d’ajouter cette version ” elior´e” dans notre programme,
sans ”rupture de contrat” pour les appels existants. Le compilateur utilise alors la
            e e          e e
version am´lior´e ou g´n´rale automatiquement, selon la combinaison de type.

On a appelle ce m´canisme la programmation incr´mentale : on commence par
                  e                                 e
               e e e
une version tr`s g´n´rale, et ensuite on ajoute le particulier, sans retoucher le code
client existant.
   a. enfin je...

C’est donc le compilateur qui travaille plus que nous.


        Enficiaud (INRIA)                      C++                     16-18/02/2009   137 / 201
 e
M´ta-programmation
                                   e
Programmation par templates : synth`se



 e
M´ta-programmation ?
 e                        a
R´solution de nombreuses tˆches par le compilateur
  1   e
    R´solution des types
  2     e
      Sp´cialisation

                                              Méta-fonction 1




                                Fonction 1a    Fonction 1b      Fonction 1c




        Enficiaud (INRIA)                           C++                        16-18/02/2009   141 / 201
 e
M´ta-programmation
                                   e
Programmation par templates : synth`se



 e
M´ta-programmation ?
 e                        a
R´solution de nombreuses tˆches par le compilateur
  1   e
    R´solution des types
  2     e
      Sp´cialisation

                                                             Fonction 2a    Fonction 2b
      Fonction 2           Fonction 2a         Fonction 2b




      Fonction 1           Fonction 1a         Fonction 1b
                                                                     Fonction 1




        Enficiaud (INRIA)                 C++                         16-18/02/2009   141 / 201
 e
M´ta-programmation
                                   e
Programmation par templates : synth`se

                 e
Objectifs de la m´ta-programmation
  1                                    e
      Concentration des efforts sur le d´veloppement des algorithmes
  2   Capitalisation
  3    e
      R´utilisation efficace de l’existant
  4   Portage algorithmique




        Enficiaud (INRIA)                   C++                    16-18/02/2009   142 / 201
                         Functors - objets fonctionnels
                           <functional>
                         STL & conteneurs
                           <vector>
STL                        <map>
                                            e e
                         STL & algorithmes g´n´riques
                           <limits>
                           <algorithm>




      Enficiaud (INRIA)         C++                        16-18/02/2009   143 / 201
STL
  e
Pr´sentation




La STL (Standard Template Library ) est une librairie standard 2 , distribu´e avec
                                                                            e
(pratiquement ?) tous les compilateurs C++.
Elle fournit des services minimaux, comme des structures template de ”container ”
 ee
(´l´ments contenant), des algorithmes d’exploitation et des classes utilitaires de
                                       a      e
renseignement. Elle participe beaucoup ` la cr´ation d’algorithmes templates.
          e                      a
Il faut tr`s souvent faire appel ` la STL
                                              e
Utiliser la STL est bon pour votre productivit´




            e        a       e
    2. ie. r´pondant ` des sp´cifications fonctionnelles strictes
             Enficiaud (INRIA)                     C++              16-18/02/2009   144 / 201
             e e
Algorithmes g´n´riques
Functors & objets fonctionnels - rappel

Definition (functor)
Un functor est une structure proposant l’interface d’une fonction.

                                        e
Il s’agit donc d’un objet, qui est par d´finition plus riche qu’une fonction, et qu’il
est possible d’appeler comme une fonction.
1   struct s functor dumb limited {
2                                             e                                                                   e       e
       // ! S u r c h a r g e de l ’ o p ´ r a t e u r o p e r a t o r ( ) , i n d u i s a n t l e comportement d ´ s i r ´
3      b o o l o p e r a t o r ( ) ( c o n s t b o o l b ) c o n s t throw ( ) { r e t u r n ! b ; }
4   };
5
6   s f u n c t o r d u m b l i m i t e d op ;
7   a s s e r t ( ! op ( t r u e ) ) ;


      e e
Plus g´n´ralement, un functor permet de faire des choses plus puissantes que des
fonctions.
`
A ne pas confondre...
1   s f u n c t o r d u m b l i m i t e d op ;              e
                                                   // d ´ c l a r a t i o n d ’ un o b j e t op de t y p e s f u n c t o r d u m b l i m i t e d ;
2   s f u n c t o r d u m b l i m i t e d op ( ) ;          e                                                              e
                                                   // d ´ c l a r a t i o n d ’ une f o n c t i o n op , s a n s p a r a m ` t r e s e t r e t o u r n a n t un o b j e t
               de t y p e s f u n c t o r d u m b l i m i t e d




             Enficiaud (INRIA)                                                     C++                                                        16-18/02/2009          145 / 201
             e e
Algorithmes g´n´riques
<functional>

 Definition
                                                                                e
 ”<functional>” Propose des functors utilitaires ainsi que des adapteurs pour cr´er
 ”facilement” des functors.
 Exemples :
1     // f u n c t o r v e r s i o n de <, >, <=, >=
2     std : : less , std : : greater , std : : less equal , std : : greater equal ;
3     s t d : : p l u s , s t d : : minus , s t d : : m u l t i p l i e s , s t d : : d i v i d e s ; // +, −, ∗ , /



 ”std :: ptr fun”
                     e               a
 fonction template cr´ant un functor ` partir d’une fonction (binaire ou unaire)

 1            e
      // D ´ c l a r a t i o n d ’ une f o n c t i o n b i n a i r e
 2    v o i d f o n c t i o n b i n a i r e ( c o n s t i n t &, c o n s t f l o a t &) ;
 3
 4    // . . .
 5    s t d : : l i s t <i n t > l ( 1 0 0 ) ;
 6
 7                                                                 e
      // r e m p l i t l a l i s t e a v e c d e s nombres a l ´ a t o i r e s
 8    s t d : : g e n e r a t e n ( l . begin ( ) , 100 , rand ) ;
 9
10                                               e
      // t r i e l a l i s t e a v e c un p r ´ d i c a t : n o t r e f o n c t i o n
11                         e
      // t r a n s f o r m ´ e en f u n c t o r
12    l . sort ( std : : ptr fun ( f o n c t i o n b i n a i r e ) ) ;




 Trouver les erreurs !
                Enficiaud (INRIA)                                                            C++                        16-18/02/2009   146 / 201
             e e
Algorithmes g´n´riques
<functional> (2)




                                                                          e
 ”std :: bind1st” / ”std :: bind2nd” : fonctions mettant un des deux param`tres d’une
                   a
 fonction binaire ` une constante
              e
 Le functor r´sultant devient unaire.

 1          e
     // D ´ c l a r a t i o n d ’ une f o n c t i o n b i n a i r e
 2   i n t f o n c t i o n b i n a i r e ( c o n s t i n t &, c o n s t f l o a t &) ;
 3
 4   // g e n e r a t i o n de s t d : : l i s t <i n t > l
 5
 6   // t r i e l a l i s t e a v e c n o t r e f o n c t i o n
 7   std : : transform (
 8     l . b e g i n ( ) , l . end ( ) , l . b e g i n ( ) ,
 9     std : : bind2nd (
10         std : : ptr fun ( f o n c t i o n b i n a i r e ) ,
11         0.34 f )
12     );




              Enficiaud (INRIA)                                                           C++   16-18/02/2009   147 / 201
<vector>
Tableau dynamique




                        ıt
Bon, tout le monde connaˆ ?




       Enficiaud (INRIA)       C++   16-18/02/2009   148 / 201
<map>
Tableau associatifs

Definition (”map”)
                                      a
Une ”map” est un tableau associatif : ` chaque clef, elle associe une valeur.

                                                                  e
      Le type de la clef et celui de la valeur sont les deux param`tres templates
      obligatoires.
               e          e       e
      Un troisi`me param`tre tr`s utile donne la fonction d’ordre sur la clef. Il vaut
           e                                   e               <”
      par d´faut le functor ”std :: less ” (inf´rant un ordre ” sur l’espace des clefs).
                 e                              e               e
L’ordre est donn´ par un functor, il est donc tr`s facile d’en d´finir un sur une
structure de clef complexe.

”                      e                             e
 map” garantie l’unicit´ des clefs, mais selon le mod`le suivant :
                                     e
Soit k1 et k2 deux clefs, P est le pr´dicat d’ordre.

                           ¬P(k1 , k2 ) ∧ ¬P(k2 , k1 ) ⇒ k1´quivalent ` k2
                                                           e          a

Si la relation d’ordre n’est pas correctement construite, on peut avoir des
mauvaises surprises.
        Enficiaud (INRIA)                         C++                         16-18/02/2009   149 / 201
<map>
Exercice

      e
 Enonc´
 Soit la structure suivante :
1        s t r u c t s my key {
2            int coarse order ;
3            float fine order ;
4        };



     1      La transformer pour qu’elle soit compatible avec ”std :: map” et avec l’ordre
            par d´faut. On souhaite associer ” my key” ` des chaˆ
                 e                            s         a                       e
                                                                  ınes de caract`res.
     2      On souhaite avoir plusieurs ordres totaux. Proposez une approche avec des
            functors.

 1       s t d : : map<s m y k e y , s t d : : s t r i n g > my map ;
 2       s my key k [ 1 0 0 ] ;
 3
 4   f o r ( i n t i = 0 ; i < 1 0 0 ; i ++) {
 5       k [ i ] . c o a r s e o r d e r = 100 − i − 1 ;
 6       k [ i ] . f i n e o r d e r = i / 10. f ;
 7       std : : ostringstream o ;
 8       o << " my_string_ " << i << " _ " << k [ i ] . c o a r s e o r d e r << " _ " << k [ i ] . f i n e o r d e r ;
 9       my map [ k ] = o . s t r ( ) ;
10   }
11   a s s e r t ( my map . c o u n t ( ) == 1 0 0 ) ;



                 Enficiaud (INRIA)                                          C++                                            16-18/02/2009   150 / 201
<limits>
                  e
Renseignements num´riques




<limits>
                                                            e
”<limits>” contient des informations relatives aux types num´riques. Elle contient
                                    T” <numeric limits>” qui donne des
principalement une classe template ” , ”
                             e      T”
informations sur le type num´rique ” .

               T”,                           e           e
Soit un type ” ”std :: numeric limit <T>” d´finie des m´thodes statiques
                                           e    a
(accessible sans instance) permettant d’acc´der ` un ensemble de fonctions
              T”
renseignant ” :
1   std   ::   n u m e r i c l i m i t <T> : : max ( ) ;           // f o n c t i o n s t a t i q u e r e t o u r n a n t l e maximum p o s s i b l e p o u r l e t y p e T
2   std   ::   n u m e r i c l i m i t <T> : : min ( ) ;           // l e minimum p o s s i b l e p o u r l e t y p e T
3   std   ::   n u m e r i c l i m i t <T> : : i s i n t e g e r ( ) ;               e
                                                                        // b o o l ´ e n i n d i q u a n t que T e s t b i e n un t y p e e n t i e r
4   std   ::   n u m e r i c l i m i t <T> : : e p s i l o n ( ) ;                                                               e
                                                                        // v a l e u r i n d i q u a n t l a l i m i t e n u m´ r i q u e d ’ i n d i s t i n c t i o n e n t r e deux
                  T successifs




               Enficiaud (INRIA)                                                         C++                                                          16-18/02/2009            151 / 201
<limits>
Exemple d’utilisation




Initialisation correcte de l’algorithme en cas de liste vide :

Exemple sur l’initialisation
   e
  D´claration                                                                           Utilisation

                                                                                        1    s t d : : v e c t o r <i n t > v1 ;
  1    t e m p l a t e < c l a s s T> typename T : : v a l u e t y p e                  2    s t d : : l i s t <d o u b l e > l 1 ;
                    m i n o f c o l l e c t i o n (T i t , T i t e ) {                  3    f o r ( i n t i = 0 ; i < 1 0 0 ; i ++) {
  2        t y p e d e f typename T : : v a l u e t y p e v t ;                         4        double v a l = rand () ;
  3        v t m i n v a l = s t d : : n u m e r i c l i m i t s <v t > : : max         5        v1 . p u s h b a c k ( s t a t i c c a s t <i n t >( v a l ∗ 1000 +
                       () ;                                                                                   0.5) ) ;
  4        f o r ( ; i t != i t e ; ++i t )                                             6        l 1 . push back ( v a l ) ;
  5            i f ( min val < ∗i t )                                                   7    }
  6                min val = ∗i t ;                                                     8    s t d : : c o u t << m i n o f c o l l e c t i o n ( v1 . b e g i n ( ) , v1
  7        return min val ;                                                                               . end ( ) ) << s t d : : e n d l ;
  8    }                                                                                9    s t d : : c o u t << m i n o f c o l l e c t i o n ( l 1 . b e g i n ( ) , l 1
                                                                                                          . end ( ) ) << s t d : : e n d l ;




            Enficiaud (INRIA)                                                      C++                                                        16-18/02/2009            152 / 201
             e e
Algorithmes g´n´riques
Utilisation de <algorithm>



                                                                     e
 La partie <algorithm> de la STL propose une suite d’algorithmes fr´quemment
       e
 utilis´es : tri, partition, ordre lexicographique, etc.
                         e          e e                                   e
 Les algorithmes se d´clinent g´n´ralement en plusieurs variantes qui se d´clinent
 suivant les types en entr´e. e

 Exemple
1    void d o s o m e s t u f f o n l i s t ()
2    {
3      s t d : : l i s t <d o u b l e > l ( 1 0 0 ) ;
4                                                                                                               e e                                                  a
       s t d : : g e n e r a t e n ( l . b e g i n ( ) , 1 0 0 , r a n d ) ; // ” g e n e r a t e n ” : g ´ n ´ r a t i o n de c o n t e n e u r p a r N a p p e l s ` une
                    fonction
 5     s t d : : l i s t <d o u b l e > : : i t e r a t o r i t = s t d : : f i n d ( l . b e g i n ( ) , l . end ( ) , 2 0 ) ; // r e c h e r c h e
 6                                                                                                                     e e
       i t = s t d : : m a x e l e m e n t ( l . b e g i n ( ) , l . end ( ) ) ; // i t e r a t e u r s u r l ’ ´ l´ m e n t maximal de l ’ e n s e m b l e
 7     s t d : : s t a b l e s o r t ( l . b e g i n ( ) , l . end ( ) ) ;                              e
                                                                                  // o r d r e p r ´ s e r v a n t l e s p o s i t i o n s r e l a t i v e s
 8
 9       s t d : : f o r e a c h ( l . b e g i n ( ) , l . end ( ) , s t d : : b i n d 1 s t ( s t d : : m u l t i p l i e s <d o u b l e >() , 3 ) ) ;
10
11   }




               Enficiaud (INRIA)                                                              C++                                                          16-18/02/2009   153 / 201
 Patrons de               e
                        It´rateurs
conception (Design      Singletons
patterns)




     Enficiaud (INRIA)         C++    16-18/02/2009   154 / 201
Patrons de conception
 e
D´finition


Definition (Patron de conception)
Les patrons de conception (en anglais Design Patterns) sont des propositions de
                                   e      e           e                 e
conception informatiques largement ´prouv´es dans la r´solution de probl`mes
 e
g´nie logiciel types.

                               e
     De nombreux patrons sont d´finis (cf. Wikipedia), nous en verrons quelques
     uns
                                              e
     La STL utilise abondamment la notion d’it´rateur qui est un patron de
     conception
                 e        a
     Le C++ se prˆte bien ` l’utilisation de patrons...

   e
Am´liore grandement le travail collaboratif (non intrusion de notions
     e            e
compl´mentaires, s´paration fonctionnelle...)

Mais les patrons de conception restent des propositions (pouvant vous donner des
  e                     e
id´es) et suivre ces mod`les n’est pas une fin en soi.
        Enficiaud (INRIA)                C++                        16-18/02/2009   155 / 201
Patrons de conception
  e
It´rateurs

              e
 Definition (It´rateur)
      e                                             e
 Un it´rateur est un objet ayant une interface limit´e, permettant de parcourir tout
 ou partie d’un objet contenant.

 Avantage
                  e
 Cet objet interm´diaire de parcours isole l’algorithme client de la structure interne
                                                      ıtre
 du contenant : l’algorithme n’a pas besoin de connaˆ comment est constitu´       e
 l’ensemble qu’il doit parcourir.

 Algorithme de moyenne
 Exemple d’utilisation... (trouver le bug)

 1    t e m p l a t e < c l a s s T> f l o a t make my mean ( c o n s t T& c o n t a i n e r ) {
 2        float m = 0;
 3        int i nb = 0;
 4        f o r ( typename T : : c o n s t i t e r a t o r i t = c o n t a i n e r . b e g i n ( ) , i t e = c o n t a i n e r . end ( ) ;
 5            i t != i t e ;
 6           ++i t ) {
 7           m += ∗ i t ;
 8            i n b ++;
 9        }
10        return m / i nb ;
11    }


               Enficiaud (INRIA)                                                        C++                                                   16-18/02/2009   156 / 201
Patrons de conception
  e
It´rateurs

  e
It´rateur : interface
   1                   e                    e                             e
       test de fin d’it´ration : pour un it´rateur en C++, un couple d’it´rateur est
        e                        e                                      e     e
       n´cessaire : le premier it`re, le second marque la fin. Un test d’´galit´ permet
                 e                        e
       alors de d´terminer la fin de l’it´ration
   2       e               e e                                 e
       incr´mentation ou d´cr´mentation : avance ou recule l’it´rateur d’un (ou
                  ee
       plusieurs) ´l´ment(s)

                             e    e
       le test de fin est impl´ment´ en surchargeant l’”operator!=” de la classe de
           e
       l’it´rateur
             e                  e    e
       l’incr´mentation est impl´ment´e en surchargeant l’”operator++” de la classe
              e
       de l’it´rateur

                                                 e e ++it” et le post-fix´
Il existe deux versions de l’”operator++” : le pr´fix´ (”   )               e
          ).                                                    ee
(”it ++” Le premier ne prend pas d’argument et retourne une r´f´rence sur
lui-mˆme (”return ∗ this ”). Le second prend un argument entier (non utilis´) et
      e                                                                    e
                              e            e
retourne une copie de lui-mˆme avant incr´mentation.

         Enficiaud (INRIA)                 C++                         16-18/02/2009   157 / 201
Patrons
Singletons


Definition (singleton)
                                   e
Assure qu’une classe n’est instanci´e qu’une seule et unique fois.

Utile dans certains contextes : par exemple une classe de synchronisation de
                                      e e
ressources, une classe de mappage d’´v`nements, etc.

              e
Exemple d’impl´mentation
  Template de singleton                                                                Classe singleton

  1    t e m p l a t e < c l a s s T> c l a s s s i n g l e t o n {
  2        static T singleton object ;
  3    public :
  4        s t a t i c T& G e t I n s t a n c e ( ) {
                                                                                       1    // E c r i r e l a c l a s s e E x e m p l e S i n g l e t o n
  5            return singleton object ;
                                                                                                     u t i l i s a n t l e template pr´c´dent  e e
  6        }
                                                                                       2    class ExempleSingleton ;
  7    };
  8
  9    t e m p l a t e < c l a s s T>
 10        T s i n g l e t o n <T> : : s i n g l e t o n o b j e c t = T ( ) ;




Ecrire la classe ”ExempleSingleton” (utilisation minimale du singleton).

            Enficiaud (INRIA)                                                     C++                                                      16-18/02/2009      159 / 201
                                      e
                   Formation C++ avanc´e



          J3 : Librairies externes et organisation de code




Enficiaud (INRIA)                C++                      16-18/02/2009   162 / 201
J3 : Librairies externes et organisation de code
Contenu




10   Librairies externes

11   Extension C++ avec Boost

12   Optimisation




          Enficiaud (INRIA)      C++                16-18/02/2009   163 / 201
                                         e
                        Compilation et ´dition de liens
Librairies externes              e
                        Visibilit´ du code & interfaces




     Enficiaud (INRIA)         C++                         16-18/02/2009   164 / 201
Librairies externes
       c
Interfa¸age avec le ”C”




                       c
Le C++ permet l’interfa¸age ”natif” avec le C

                                                            e
Il faut pour cela que les types C soit correctement renseign´s (au compilateur
                e
C++) comme ´tant C.

                             e
Lorsque l’on compile une unit´ de code en C++ :
   1   la macro                                 e
                        cplusplus est toujours d´finie (tout compilateur confondu)
   2   la directive extern ”C” permet alors de renseigner le type (structure, fonction)




         Enficiaud (INRIA)                     C++                        16-18/02/2009   165 / 201
Librairies externes
       c
Interfa¸age avec le C : exemple




            e
Exemple de d´claration
   e
  D´claration d’un header compatible avec le C et le C++                        Utilisation

  1   // f i c h i e r t o t o . h : h e a d e r C/C++
                                                                                1    // f i c h i e r t o t o . cpp
  2   #i f d e f     cplusplus
                                                                                2    #i n c l u d e " toto . h "
  3   e xt e rn "C" {
                                                                                3
  4   #e n d i f
                                                                                4    class toto : public s toujours c {
  5
                                                                                5       t o t o ( ) : i ( 1 0 0 ) {}
  6   #i n c l u d e " header_c . h " // i n c l u s i o n de
                                                                                6       void i n i t () {
                    e
                  d´claration C
                                                                                7           d o p r o c e s s ( s t a t i c c a s t <s t o u j o u r s c ∗>(
  7
                                                                                                      this )) ;
  8    struct s toujours c {
                                                                             8          }
  9       int i ;
                                                                             9       };
 10       i n t ∗t a b ;
                                                                            10
 11       /∗ . . . ∗/
                                                                            11       // f i c h i e r t o t o . c
 12    };
                                                                            12       #i n c l u d e " toto . h "
 13
                                                                            13
 14    v o i d d o p r o c e s s ( s t r u c t s t o u j o u r s c ∗) ;
                                                                            14       v o i d d o p r o c e s s ( s t r u c t s t o u j o u r s c ∗s ) {
 15
                                                                            15          s− a b = ( i n t ∗) m a l l o c ( s . i ∗ s i z e o f ( i n t ) ) ;
                                                                                            >t
 16   #i f d e f  cplusplus
                                                                            16          /∗ . . . ∗/
 17   } // a c c o l a d e f e r m a t e e x t e r n ”C ”
                                                                            17       }
 18   #e n d i f




            Enficiaud (INRIA)                                              C++                                                       16-18/02/2009              166 / 201
         e
Visibilit´ du code & interface
Remarques sur les inclusions


Remarque 1
                    e                                 e            e
Il n’existe pas de m´canisme trivial pour cacher des d´tails d’impl´mentation.

”                                                           e
 private/protected/public” ne sont que des directives destin´es au compilateur, et
indiquant approximativement l’usage des membres d’une classe.

Remarque 2
                         e               e              ıt
Le nombre de types utilis´s pour les impl´mentations croˆ rapidement.

Pour qu’un utilisateur externe puisse utiliser une classe, il faut qu’il manipule tous
               e                                                                 e
les types des m´thodes que cette classe appelle, ainsi que tous les types utilis´s
           e
pour l’impl´mentation.

                      e       a
Ces deux points sont gˆnants, ` la fois
     pour le fournisseur (divulgation)
     pour l’utilisateur (pollution)

        Enficiaud (INRIA)                  C++                         16-18/02/2009   167 / 201
         e
Visibilit´ du code & interface
Rappel



Interfaces
                                    a     e
Les interfaces permettent d’arriver ` un r´sultat correct pour les deux parties, pour
         u e
un surcoˆt n´gligeable.

                                                                       e
     Elles laissent le soin au fournisseur de service de modifier l’impl´mentation,
                                                e
     tant que l’interface du service reste la mˆme
              e                         e            e
     Elles empˆchent la divulgation de d´tails d’impl´mentation
           e                                                    e a        e
     Elles ´vitent au client le fardeau de la gestion de type li´s ` l’impl´mentation
     du fournisseur
                                                                       e
     Elles sont compatibles avec les templates et potentiellement la pr´sence de
     beaucoup de types
                           a
     Elles restent souples ` manipuler pour le client



         Enficiaud (INRIA)                C++                          16-18/02/2009   168 / 201
                         e
                       Pr´sentation
                       Modes d’utilisation & compilation
 Extension C++         filesystem
avec Boost             Tests unitaires
                       Thread




    Enficiaud (INRIA)         C++                       16-18/02/2009   169 / 201
Boost
  e
Pr´sentation


                                                    e
Boost (http ://www.boost.org) est un Consortium de d´veloppeur C++,
travaillant sur des extensions standards du C++.

Licence
La licence d’utilisation est d’exploitation de Boost est permissive et non intrusive
                                                       a
(redistribution sans restriction dans des programmes ` but commercial ou non,
sans obligation de mention ni redistribution des sources).
Il faut utiliser Boost.
Utiliser Boost est une bonne chose, car Boost vous veut du bien.
Il faut convaincre tout le monde d’utiliser Boost.
Boost est le prochain standard.




             Enficiaud (INRIA)                                      C++   16-18/02/2009   170 / 201
Boost
Modes d’utilisation

         e
Deux mani`re d’utiliser Boost :
    1                        a                    e                       e
         version ”headers” : ` inclure dans l’unit´ de compilation concern´e, et c’est
         tout (ex. : graph, mpl, proto, fusion, asio...)
    2                    e                                      e
         version compil´e : certaines (peu) parties de Boost n´cessitent une
         compilation, et (donc) une liaison avec le programme client (ex. : filesystem,
         regex, mpi,...)
                                     a
Il faut utiliser Boost, c’est simple ` installer.




              Enficiaud (INRIA)                      C++                16-18/02/2009   171 / 201
Boost
Compilation et installation



      Unises (Unix, Linux, Mac, Cygwin, ...)
        1   $ cd path/to/boost_1_37_0
        2   $ ./configure --prefix=path/to/installation/prefix
        3   $ make install
      Windows avec MS Visual Studio
        1     e                                                             e
            D´marrer la ligne de commande Visual (normalement dans le menu d´marrer
                        e
            et dans le r´pertoire de Visual)
        2   $ cd path/to/boost_1_37_0/tools/jam
        3   $ build.bat
        4   $ cd path/to/boost_1_37_0
        5   $ copy path/to/-
            boost_1_37_0/tools/jam/src/bin.Quelquechose/bjam .
        6   $ bjam --build-dir=D:\temporary_dir --toolset=msvc --build-
            type=complete stage




         Enficiaud (INRIA)                 C++                        16-18/02/2009   172 / 201
Boost
<boost/filesystem>

 Objectif
                                                                 e
 Propose une abstraction plate-forme pour la manipulation du syst`me de fichiers.

                                                                           e
 Ex. : nom des fichiers, gestion de l’arborescence, gestion des droits d’acc`s,
 existence, etc.

           e
 Il faut pr´alablement compiler la partie correspondante de Boost (”  with-filesystem”
                                                                   e
 dans bjam), et lier (linker) avec ”boost filesystem ” lors de la cr´ation du
 programme.

       e           e
 Concat´nation de r´pertoires
 1   #i n c l u d e <b o o s t / f i l e s y s t e m . hpp>
 2   #i n c l u d e <b o o s t / f i l e s y s t e m / f s t r e a m . hpp>
 3   namespace f s = b o o s t : : f i l e s y s t e m ;
 4
 5   f s : : path d i r ( "." ) ;           // o b j e t de t y p e ”p a t h ”
 6
 7   f s : : p a t h new p = d i r / " new_p " / " file_set " / " my_new_file " ; // ” o p e r a t o r / ” o v e r l o a d
 8   new p . c r e a t e d i r e c t o r i e s ( new p . p a r e n t p a t h ( ) ) ;
 9
10   s t d : : o f s t r e a m m y f i l e ( new p ) ;
11   m y f i l e << " toto " << s t d : : e n d l ;
12   my file . close () ;


               Enficiaud (INRIA)                                                  C++                                         16-18/02/2009   173 / 201
Boost
<boost/filesystem> : exemple

  e
 D´termination du type d’un chemin
 1   #i n c l u d e <b o o s t / f i l e s y s t e m . hpp>
 2   namespace f s = b o o s t : : f i l e s y s t e m ;
 3   // . . .
 4   s t d : : s t r i n g f i l e n a m e = " m y_fi le_o r_f ile " ;
 5   f s : : path f i l e ( f i l e n a m e ) ;         // o b j e t de t y p e ”p a t h ”
 6   if (! fs : : exists ( f i l e ))
 7       s t d : : c o u t << " file \" " << f i l e n a m e << " \" does not exists ! " ;
 8
 9   fs : : f i l e s t a t u s stat = fs : : status ( f i l e ) ;
10   s t d : : c o u t << " This is a " ;
11   switch ( s t a t . type () ) {
12   c a s e f s : : r e g u l a r f i l e : // a f f i c h a g e de l a t a i l l e p o u r l e s f i c h i e r s
13       s t d : : c o u t << " regular file of size " << f s : : f i l e s i z e ( f i l e ) << s t d : : e n d l ;
14       break ;
15
16   c a s e f s : : d i r e c t o r y f i l e : // l i s t e d e s f i c h i e r e t nombre de f i c h i e r p o u r un r ´ p e r t o i r ee
17       {
18           s t d : : c o u t << " directory containing " << s t d : : e n d l ;
19           int i = 0;
20           f o r ( f s : : d i r e c t o r y i t e r a t o r i t r ( f i l e ) ; i t r != f s : : d i r e c t o r y i t e r a t o r ( ) ; ++ i t r )
21           {
22               i ++;
23               s t d : : c o u t << " \ t " << i t r − a t h ( ) . f i l e n a m e ( ) << s t d : : e n d l ;
                                                               >p
24           }
25           s t d : : c o u t << s t d : : e n d l << i << " files " << s t d : : e n d l ;
26       }
27       break ;
28   default :
29       s t d : : c o u t << " Unknown type " ;
30       break ;
31   }
32   // . . .


              Enficiaud (INRIA)                                                          C++                                                              16-18/02/2009   174 / 201
Boost
<boost/test>




But
                                   e                                 e
Proposer un ensemble d’outils pour ´crire des tests unitaires et de r´gression
robustes.
                              e
La librairie attend que nous d´finissions une fonction
1     b o o s t : : u n i t t e s t : : t e s t s u i t e ∗ i n i t u n i t t e s t s u i t e ( i n t a r g c , c h a r∗ a r g v [ ] ) ; // a v e c a r g u m e n t s l i g n e de
                    commande
2     b o o l i n i t u n i t t e s t s u i t e ( ) ; // p l u s s i m p l e


                               e                                      e
Le corps de cette fonction va d´clarer nos suites de tests, de la mani`re suivante :
1   void test case1 () ;
2   t e s t s u i t e∗ i n i t u n i t t e s t s u i t e () {
3       t e s t s u i t e ∗ t s 1 = BOOST TEST SUITE ( " test suite 1 " ) ;
4       t s 1− >add ( BOOST TEST CASE(& t e s t c a s e 1 ) ) ;
5   }


              e                                                e
Les tests ne d´marreront qu’au retour de cette fonction de de d´claration.



            Enficiaud (INRIA)                                                        C++                                                          16-18/02/2009            177 / 201
Boost
<boost/test> : exemple




 Exemple de test
 1   void test case1 () {
 2     BOOST CHECK( 1 == 1 ) ;     // t e s t 1
 3                                                                                        e
       BOOST CHECK MESSAGE( 1 == 2 , " seems that 1 != 2 " ) ; // t e s t ´ c h o u e a v e c un message , m a i s i l c o n t i n u e
 4     BOOST CHECK THROW( throw s t d : : r u n t i m e e x c e p t i o n ( " blablabla " ) , s t d : : r u n t i m e e x c e p t i o n ) ; // t e s t de t h r o w
 5                                                                                                                 e
       BOOST ERROR( " message d ’ erreur " ) ; // m e s s a g e d ’ e r r e u r e t e r r e u r e n r e g i s t r ´ e
 6
 7       BOOST CHECH EQUAL(2+2 , 4 ) ;            // t e s t
 8
 9       BOOST REQUIRE ( t r u e ) ;                   e
                                            // d o i t ˆ t r e v r a i p o u r c o n t i n u e r c e t e s t .
10   }




              Enficiaud (INRIA)                                                  C++                                                  16-18/02/2009          178 / 201
Boost
<boost/thread.hpp>




Objectif
Propose une abstraction plate-forme pour la manipulation des threads.
Propose des manipulateurs haut niveau pour la gestion des threads.


          e
Il faut pr´alablement compiler la partie correspondante de Boost (” with-thread
                                                       e
dans bjam), et linker avec ”boost thread” lors de la cr´ation du programme.

Quelques objets de ”boost : :thread”
1   boost : : thread t ;       // un t h r e a d
2   boost : : thread group g ;     // g r o u p e de t h r e a d s




           Enficiaud (INRIA)                                          C++   16-18/02/2009   179 / 201
Boost
<boost/thread.hpp> : exemple de functor

                                        e e
 Objet fonctionnel dont le corps sera ex´cut´ dans un thread
 1   #i n c l u d e <b o o s t / t h r e a d / t h r e a d . hpp>
 2   #i n c l u d e " boost / date_time / posix_time / p o si x _t i me _ ty p es . hpp "
 3   u s i n g namespace b o o s t : : p o s i x t i m e ;        // p o u r l e s s l e e p s
 4
 5      struct my functor {
 6        int init value1 ;
 7        m y f u n c t o r ( i n t i n i t v a l u e 1 ) : i n i t v a l u e 1 ( i n i t v a l u e 1 ) {}
 8      // c o r p s du t h r e a d
 9        void operator () ()
10        {
11           boost : : t h i s t h r e a d : : d i s a b l e i n t e r r u p t i o n di ;
12           {
13               s t d : : c o u t << " Thread ( functor ) inited with " << i n i t v a l u e 1 << s t d : : e n d l ;
14               s t d : : c o u t << " Thread id is " << b o o s t : : t h i s t h r e a d : : g e t i d ( ) << s t d : : e n d l ; // i d e n t i f i a n t
15           }
16
17               i n t count = 0;
18               w h i l e ( ! b o o s t : : t h i s t h r e a d : : i n t e r r u p t i o n r e q u e s t e d ( ) ) // t e s t de demande d ’ i n t e r r u p t i o n
19               {
20                   // s e c t i o n s a n s i n t e r r u p t i o n
21                   boost : : t h i s t h r e a d : : d i s a b l e i n t e r r u p t i o n di ;
22                   {
23                       s t d : : c o u t << " . " << c o u n t++ << s t d : : e n d l ;
24                       i f ( count % i n i t v a l u e 1 )
25                           s t d : : c o u t << s t d : : e n d l ;
26                   }
27                   b o o s t : : t h i s t h r e a d : : s l e e p ( t i m e d u r a t i o n ( 0 , 0 , 0 , 1 0 0 ) ) ; // s l e e p de 2 s e c o n d e s
28               }
29           }
30      };




                 Enficiaud (INRIA)                                                          C++                                                            16-18/02/2009   180 / 201
Boost
<boost/thread.hpp> : exemple d’appel




 Programme de test (sur un groupe de threads)
 1   void t e s t () {
 2     boost : : thread group g ;                    // g r o u p e de t h r e a d
 3
 4       f o r ( i n t i = 1 ; i < 1 0 ; i ++)
 5       {
 6           b o o s t : : t h r e a d ∗m y t h r e a d = new b o o s t : : t h r e a d ( m y f u n c t o r ( i ∗300) ) ;
 7           // b o o s t : : t h r e a d m y t h r e a d ( m y f u n c t o r ( i ∗300) ) ;
 8           g . add thread ( my thread ) ;
 9       }
10       s t d : : c o u t << " Init end " << s t d : : e n d l ;
11       char c = 0;
12       s t d : : c o u t << " Press a key " << s t d : : e n d l ;
13       w h i l e ( ! ( s t d : : c i n >> c ) ) {
14       }
15
16       g . i n t e r r u p t a l l () ;   // l a n c e un s i g n a l d ’ i n t e r r u p t i o n
17       g . j o i n a l l () ;           // a t t e n d l a f i n de t o u s l e s t h r e a d s
18
19       s t d : : c o u t << " end of all threads " << s t d : : e n d l ;
20   }




               Enficiaud (INRIA)                                                         C++                                 16-18/02/2009   181 / 201
                                  e e
                       Questions g´n´rales
Optimisation           Conteneurs
                       Optimisations logicielles




    Enficiaud (INRIA)         C++                   16-18/02/2009   183 / 201
Optimisation
           e e
Questions g´n´rales autour du C++

     ”Premature optimization is the root of all evil” (Donald Knuth)

Que veut dire optimisation ?

On optimise toujours en fonction d’une ou plusieurs contraintes... Ex. : temps de
                     e
calcul, occupation m´moire, algorithmique...
Les contraintes sont parfois contradictoires et/ou conflictuelles.

             u
Definition (Coˆt algorithmique)
   u     e                           e             a                     e
Coˆt th´orique de l’algorithme exprim´ par rapport ` la taille N des donn´es
trait´es et exprim´ en O(†(N)), pour N ∈ N∗ .
     e            e

† : 1 (temps constant), identit´, polynˆme, log ...
                               e       o




        Enficiaud (INRIA)                 C++                       16-18/02/2009   184 / 201
Optimisation
           e e
Questions g´n´rales autour du C++

Rappels importants
  1         u                         a            e
      Le coˆt est asymptotique, c’est-`-dire exprim´ pour N grand (ce qui n’est pas
          e
      syst´matiquement le cas).
  2                    a                 e            e
      O(†(N)) est vrai ` une constante pr`s, qui peut ˆtre potentiellement
      importante !




        Enficiaud (INRIA)                C++                         16-18/02/2009   185 / 201
Optimisation
           e e
Questions g´n´rales autour du C++

Questions classiques :
  1   Le C++ est plus lent que le C : vrai ou faux ?
        e           e         e                                 e
      R´ponse mitig´e. D’exp´rience : vrai pour des parties isol´es de code, faux
                                                 e     e
      pour des projets d’envergure importante. Mˆme d´bat entre le C et
      l’assembleur par exemple...
  2     u
      O` et quand optimiser ?
      Une fois qu’on a enfin un truc qui fonctionne, selon un design relativement
      correct.
                                                e
      Remarque : les contraintes influencent n´cessairement la phase de design,
                                                               o
      donc inutile de faire de l’optimisation logicielle trop tˆt.
  3   Comment optimiser ?
      Encore une fois, selon la contrainte.
                          ee
Nous allons voir quelques ´l´ments d’optimisation algorithmique et logicielle...




        Enficiaud (INRIA)                 C++                         16-18/02/2009   186 / 201
Optimisation
Choix des conteneurs




Alerte ! Alerte ! Alerte !
Le choix du conteneur est FONDAMENTAL !
                  e
Le choix est dirig´ par l’utilisation qu’on compte en faire :
  1   Si l’ordre d’insertion est important
  2                                            u                       e
      Si on va parcourir l’ensemble contenu (coˆt et performance des it´rateurs)
  3               e        ee                    a
      Si on va ins´rer des ´l´ments relativement ` d’autres (et non simplement en
       e
      d´but ou fin)
  4   ...
      u        e                                e
Les coˆts d’acc`s des conteneurs standards sont ´galement standards ! Donc
garantie multi plate-forme.




            Enficiaud (INRIA)                 C++                    16-18/02/2009   187 / 201
Optimisation
Choix des conteneurs (1)




std : :vector
  1           ee          e
      ajout d’´l´ment en d´but ou fin en O(1)
  2      e      ee
      acc`s aux ´l´ments en O(1)
  3       e
      requˆte de taille en O(1)
  4   parcours en αv O(N), avec αv ≈ 1, avec possibilit´ d’avoir αv < 1
                                                       e
  5               ee
      insertion d’´l´ment en O(N) (recopie) ! dramatique, ne pas faire avec
      vecteur...




        Enficiaud (INRIA)                C++                         16-18/02/2009   188 / 201
Optimisation
Choix des conteneurs (2)




std : :list
  1           ee          e
      ajout d’´l´ment en d´but ou fin en O(1)
  2      e      ee
      acc`s aux ´l´ments en O(N) : mauvais
  3       e                     a e
      requˆte de taille en O(1) ` v´rifier
  4   parcours en αl O(N), avec αl ≈ 1, mais αl > αv
  5               ee
      insertion d’´l´ment en O(1) ! bon point !




        Enficiaud (INRIA)                    C++        16-18/02/2009   189 / 201
Optimisation
               e
Comprendre et g´rer la bidouille de compilateurs

  e
Id´e
                                                           e e
Faire en sorte que le compilateur aille plus loin dans la g´n´ration d’un code
rapide et/ou compact.

Code rapide :
       Activer les flags d’optimisation
            Choix du compilateur ! !
            Options d’optimisation de plusieurs niveaux (GCC : O1, O2, 03, O45... active
            un ensemble d’optimisations)
            Choix du processeur cible
            Utilisation automatique de librairies externes (open MP, etc)
            Profondeur des inlines
                                             e
            Utilisation des fonctions intrins`ques
                                    a e
            Optimisations globales ` l’´dition de lien
            ...
                             e
       Avantage important : m´thode d’optimisation non-intrusive

         Enficiaud (INRIA)                     C++                        16-18/02/2009   191 / 201
Optimisation
               e
Comprendre et g´rer la bidouille de compilateurs

Code rapide (suite) :
     ...
     Utilisation des inlines
        1     e
            M´thode d’optimisation intrusive !
        2   Pas vraiment une optimisation : le choix de l’inlining reste le choix du
            compilateur
     Utilisation de portions de code assembleur
        1     e
            Tr`s performant (souvent, mais pas toujours)
        2     e    e
            Tr`s sp´cifique
        3   Dur
        4     e        e
            Tr`s dur mˆme...
        5            a
            Difficile ` maintenir
        6                e
            Plate-forme d´pendant




        Enficiaud (INRIA)                      C++                           16-18/02/2009   192 / 201
                                      e
                   Formation C++ avanc´e



                         e
                    Synth`se de la formation




Enficiaud (INRIA)              C++              16-18/02/2009   196 / 201
     e
Synth`se de la formation
Contenu




          Enficiaud (INRIA)   C++   16-18/02/2009   197 / 201
         a   ıtriser
Un outil ` maˆ


Tenir compte des risques
Le code est meilleur et plus compact mais :
     risque d’hubris a (donc perte de focalisation)
          e                                e
     probl`mes de lourdeur (design, dev, ex´cution)
                                                                          ee
   a. Chez les Grecs, tout ce qui, dans la conduite de l’homme, est consid´r´ par les dieux comme
 e
d´mesure, orgueil, et devant appeler leur vengeance.


Risque majeur :
                 e                 e a
Quand on est lanc´s, pourquoi s’arrˆter ` ce dont on a besoin ? !




        Enficiaud (INRIA)                      C++                              16-18/02/2009   198 / 201
Savoir-faire



     e
Pour ˆtre performant, il faut :
      ıtriser le plus grand nombre de “trucs”
    maˆ
            ıtre                  e
    en connaˆ les avantages/inconv´nients
      e       e      e
    sp´cifier d`s le d´but (notamment les perfs)

        c
Et pour ¸a
                                                           e
le mieux est d’en faire beaucoup et d’en jeter beaucoup. It´rer.




       Enficiaud (INRIA)                 C++                        16-18/02/2009   199 / 201
    e e     e
La g´n´ricit´ “light”


“design for change”
    Commencer simple (YAGNI) a
    Rendre le code generic-friendly
                     e
    Concevoir pour l’´volutif
  a. ”You Ain’t Gonna Need It”


L’important
c’est de se fermer le moins d’options, tout en restant optimal sur ce qu’on fait
maintenant.




       Enficiaud (INRIA)                 C++                         16-18/02/2009   200 / 201
Merci de votre attention




                        Release early, release often...




     Enficiaud (INRIA)                C++                  16-18/02/2009   201 / 201

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:5
posted:2/25/2012
language:French
pages:187