Docstoc

Programmation Orientee objet et C

Document Sample
Programmation Orientee objet et C Powered By Docstoc
					Programmation Orientée Objet
          et C++

             Christophe Collard
                   Plan
   Notions de base
   Classes et Objets
   Construction et destruction d’objets
   Les fonctions amies
   La surdéfinition d’opérateurs
   Les patrons de fonctions et de classes
   Les flots
   La technique de l’héritage
   Les espaces de nommage
                                     Christophe Collard
Notions de Base




                  Christophe Collard
                                                                                                   1 octet = 8 bits
1. Les variables définies par l'utilisateur                                                        1 bit = 0 ou 1

  Type de donnée       Signification                Taille (en octets)               Plage de valeurs acceptée
  char                 Caractère                             1                               -128 à 127
  unsigned char        Caractère non signé                   1                                0 à 255
  short int            Entier court                          2                            -32 768 à 32 767
  unsigned short int   Entier court non signé               2                                0 à 65 535
                                                2 (sur processeur 16 bits)               -32 768 à 32 767
  int                  Entier                   4 (sur processeur 32 bits)        -2 147 483 648 à 2 147 483 647
                                                2 (sur processeur 16 bits)                   0 à 65 535
  unsigned int         Entier non signé         4 (sur processeur 32 bits)               0 à 4 294 967 295
  long int             Entier long                           4                    -2 147 483 648 à 2 147 483 647
  unsigned long int    Entier long non signé                 4                           0 à 4 294 967 295
  float                Flottant (réel)                       4                         -3.4*10-38 à 3.4*1038
  double               Flottant double                       8                       -1.7*10-308 à 1.7*10308
  long double          Flottant double long                 10                      -3.4*10-4932 à 3.4*104932

                                                                               Prend deux valeurs : 'true' et 'false'
                                                                               mais une conversion implicite (valant 0
                                                                               ou 1) est faite par le compilateur
                                                Même taille que le type int,   lorsque l'on affecte un entier (en
                                                 parfois 1 sur quelques        réalité toute autre valeur que 0 est
  bool                 Booléen                       compilateurs              considérée comme égale à True).


                                                                                                Christophe Collard
Déclaration et initialisation

                int n;
                                              int n = 10;
                n = 10;
  Remarque : chaque instruction se termine par un « ; »

Le qualificatif « const »
                const int n = 10;

  La valeur de « n » ne change pas.
  Expression constante = valeur calculée lors de la compilation
  Ex : ici 2*n*5 est une constante


variables locales vs variables globales

                                                            Christophe Collard
2. Les fonctions                         But : accomplir une tâche


    int
                  Fonction             float
double

 INPUTS                               OUTPUT


Attention : une fonction ne peut renvoyer qu’un seul type

Fonction standard :              float fctname (int, double)
Fonction sans argument :         float fctname ()
Fonction sans valeur de retour : void fctname (int, double)

Remarque : une fonction bien programmée peut être lue sur 1 seul écran


                                                         Christophe Collard
    3. Les boucles

                 But : effectuer plusieurs fois le même type d’opérations

     Ex: sommer les 10 premiers entiers




Attention : en C++ il faut initialiser les variables, sinon une valeur aléatoire est attribuée


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

          type du compteur
                                                    Incrémente le compteur de 1
                initialisation du compteur
                     reste dans la boucle tant que cette condition est vérifiée
                                                                       Christophe Collard
Remarque:
Les variables i et j sont locales à la fonction.
Pour renvoyer la valeur j vers l’extérieur, il faut écrire :




                                                           Christophe Collard
    4. Les entrées / sorties en C++

     Ecriture sur la sortie standard




   La bibliothèque iostream contient les déclarations nécessaires à l’utilisation
   des entrées / sorties en c++


     Interprétation

cout désigne un « flot de sortie » prédéfini
<< est un opérateur dont l’opérande de gauche est un flot
                        et l’opérande de droite est une expression de type qcq

     Ici le flot cout reçoit la valeur « bonjour »
                                                              Christophe Collard
Autre exemple




  Remarque
     Les 2 dernières lignes peuvent s’écrire :

                   cout << ’’valeur de n = ‘’ << n << endl;

  Interprétation

On transmet dans un premier temps une chaine de caractères au flot cout
Ensuite le flot est augmenté de la valeur de l’entier n

              cout sait gérer des données de différents types
                                                          Christophe Collard
Rôle de l’opérateur différent dans ces deux cas


L’opérateur a procédé au formatage (implicite) de la valeur de n pour la
transformer en une chaine de caractères.



La possibilité d’attribuer plusieurs significations à un même opérateur :
                SURDEFINITION D’OPERATEURS


Lecture sur l’entrée standard

                            cin >> n;
                            cin >> n >> p;



                                                         Christophe Collard
5. La notion de référence



  Il existe 3 façons de transmettre des variables à une fonction :



                     - transmission par valeur
                     - transmission par adresse
                     - transmission par référence




                                                        Christophe Collard
Transmission par valeur




                             n        adresse    a           adresse

 avant appel :   10 20
                                      valeur                  valeur
 début échange : 10 20
 fin échange :   20 10
 après échange : 10 20    les valeurs de n et p sont dupliquées
                          on change les valeurs des copies
                                                Christophe Collard
Transmission par adresse




                               n         adresse      a
 avant appel :   10 20
                                         valeur
 début échange : 10 20
 fin échange :   20 10
                         les valeurs de n et p ne sont pas dupliquées
 après échange : 20 10
                         on change les valeurs des originaux
                                                   Christophe Collard
Transmission par référence




                               n         adresse      a
 avant appel :   10 20
                                         valeur
 début échange : 10 20
 fin échange :   20 10
                         les valeurs de n et p ne sont pas dupliquées
 après échange : 20 10
                         on change les valeurs des originaux
                                                   Christophe Collard
    Remarques

      la transmission par référence utilise
          la simplicité de la notation de la transmission par valeur
          le mécanisme de la transmission par adresse

      L’utilisation de la transmission par référence s’écrit uniquement au
      niveau de la fonction appelée :
                         void echange (int& a, int& b)

    Attention aux effets de bord lors de l’appel de la fonction
      Appel de la fonction :     echange (n, p)


         transmission par valeur ?             transmission par référence ?


pas de modification des valeurs de n et p         valeurs de n et p modifiées
                                                             Christophe Collard
6. Surdéfinition de fonctions
 une fonction avec un même nom possède plusieurs significations




                             Que se passe t il si x est de type float,
 sosie numero 1 : a = 5      long double, …?
 sosie numero 2 : a = 2.5        conversion du type par le compilateur
                                                    Christophe Collard
7. L’allocation dynamique de mémoire
 l’opérateur NEW sert à allouer de la mémoire
 l’opérateur DELETE sert à libérer de la mémoire

L’opérateur NEW

Exemple 1



Exemple 2


 Pour allouer n éléments d’un « type » donné :                 new type [n]
 new retourne un pointeur (type*) sur le 1er élément d’un tableau

         p        adresse adresse   adresse adresse adresse


                  valeur   valeur   valeur   valeur   valeur


                   p[0]                                p[4]        Christophe Collard
L’opérateur DELETE
 libère la mémoire allouée par l’opérateur NEW
 on donne comme argument l’adresse du pointeur fournie par new

 syntaxe pour les éléments de type C++ standard

                      int* p;
                      p = new int [5];
                      delete p;

 syntaxe pour les tableaux d’objet
                      point* p;
                      p = new point [5];
                      delete [ ] p;
Attention le rôle de l’opérateur delete est très important.
Si on détruit un pointeur sans libérer correctement la mémoire,
celle-ci n’est plus accessible et ne peut être réallouée
            Stack overflow
                                                   Christophe Collard
Classes et Objets




                    Christophe Collard
    1. Classes et encapsulation des données

       Classe        généralisation de la notion de type
extension des types C++ standard à de nouveaux types définis pas l’utilisateur

                   regroupe des données et des méthodes


                         données membres         fonctions membres




       On a séparé les données et fonctions membres en 2 catégories


                     public                  private       Christophe Collard
   Encapsulation

 private : données et méthodes non accessibles à l’extérieur de la classe
           seules les fonctions membres y ont accès

 protected : données et méthodes non accessibles à l’extérieur de la classe
             accès possible par les classes dérivées (cf plus tard)

 public : données et méthodes accessibles à l’extérieur de la classe

    Remarques

pour modifier des données privées il faut passer via des méthodes publiques

En POO pure, les données sont encapsulées et leur accès ne peut se faire
que par le biais de méthodes



                                                          Christophe Collard
Définition des fonctions membres (méthodes)




  initialise méthode de point             x et y modifiables
  le symbole :: est un opérateur de résolution de portée

         l’identificateur initialise est celui défini dans la classe point
                                                           Christophe Collard
Utilisation de la classe




Remarques
  point est un nouveau type défini par l’utilisateur
  a et b sont des instances de la classe point

  a et b sont encore appelés des objets de type point
  si aucun des mots private ou public n’apparaît dans la classe, tout
  est considéré comme étant private => rien n’est accessible




                                                        Christophe Collard
Affectation d’objets




                       Christophe Collard
Affectation d’objets




               b                       a
       x             y         x             y

     adresse       adresse   adresse       adresse

                                                     copie des membres
     valeur        valeur    valeur        valeur




                                                             Christophe Collard
Affectation d’objets




Remarques
  seules les données membres sont copiée (pas les méthodes)
  ceci n’est possible que pour des objets de même type
  ce système de copie « partielle » ne fonctionne pas pour des
  données dynamiques (il faudra surdéfinir un opérateur =)
                                                      Christophe Collard
2. Constructeur et destructeur

  création d’un nouvel objet          Processus automatisé

  allocation de mémoire                 CONSTRUCTEUR

  initialisation de ses données



           Fonctions membres appelées automatiquement
                à chaque création / destruction d’objet

  destruction d’un objet              Processus automatisé

  libération de mémoire                 DESTRUCTEUR



                                                 Christophe Collard
Résultat: affiche 10 valeurs aléatoires
                                          Christophe Collard
            Exemple
Remarques
 le constructeur ne renvoie rien (même pas void)
 le constructeur porte le même nom que la classe

 a partir du moment où la classe possède un contructeur, il faut créer
 un objet avec les arguments requis pas le constructeur
              hasard suite ();       invalide ici
 une classe peu contenir plusieurs constructeurs
            constructeur par défaut
            constructeur d’initialisation des membres
            constructeur par recopie


 le destructeur ne renvoie rien et ne prend aucun argument
 le destructeur porte le nom de la classe précédé du symbole ~
 une classe ne peut contenir qu’un seul destructeur (car pas d’argument)


                                                        Christophe Collard
Attention :
le rôle du destructeur est très important.
Si on détruit un objet sans libérer correctement la mémoire, celle-
ci n’est plus accessible et ne peut être réallouée
            Stack overflow




                                                   Christophe Collard
3. Les données membres statiques
Les différents objets issus d’une même classe possèdent chacun leurs
propres données membres




La déclaration suivante
                                     point a, b;

conduit à
                              a                         b
                       x            y              x          y

                    adresse       adresse     adresse       adresse


                     valeur       valeur       valeur       valeur


                                                                      Christophe Collard
Une façon de permettre à plusieurs objets de partager des données
consiste à les déclarer avec le qualificatif static




                             a             b
                      x            n             x

                   adresse       adresse       adresse


                    valeur       valeur        valeur




Les membres statiques existent en 1 seul exemplaire, indépendamment
des objets de la classe correspondante (même si aucun objet existe)
Les membres statiques sont toujours initialisés à 0
        static int ctr = 5;        INTERDIT par le compilateur
                                                         Christophe Collard
4. Exploitation d’une classe
  Dissocier l’implémentation d’une classe de son utilisation


  Mettre dans un fichier séparé la classe et son implémentation


  Création de bibliothèques que l’on regroupe par thèmes


5. Propriétés des fonctions membres

Surdéfinition des fonctions membres


    La surdéfinition de fonctions « ordinaires » en C++ s’applique
    aux fonctions membre d’une classe, y compris au constructeur

    Elle ne peut s’appliquer au destructeur qui ne reçoit aucun argument
                                                       Christophe Collard
Exemple




          Christophe Collard
           position (0,0)
           coordonnees du point
           position (5,5)
Résultat   Point
           position (3,12)

Remarques
  N’importe quelle méthode peut appeler une autre méthode de la
  même classe (public, protected ou private).
  N’importe quelle méthode peut s’appeler elle-même (récursivité),
  mais il faut prévoir un moyen de finir le processus.
  Pour accéder aux données/méthodes private ou protected, il faut
  passer via un méthode publique de la classe.
  On peut définir dans des fonctions des arguments par défaut afin de
  limiter le nombre de fonctions surdéfinies         Christophe Collard
Arguments par défaut
 Dans la définition de la classe point, on peut remplacer
  void affiche ();
  void afficher (char*);
 par
  void affiche (char* = ‘’’’);




        void point::affiche (); est supprimée

        void point::affiche (char* message=‘’’’);
Remarque
 Ceci s’applique aussi aux constructeurs               Christophe Collard
Les objets transmis en argument d’une fonction membre
 Exemple
   définir une méthode « coincide » dans la classe point pour
   comparer 2 objets de type point

   son appel s’effectue de la manière suivante
             a.coincide (b)
   ou par symétrie du problème

             b.coincide (a)




                                                     Christophe Collard
Résultat
   a et b 0 (false)
   b et c 1 (true)
                      Christophe Collard
Remarques
 Appel du constructeur avec 1 seul argument
 point b (1);           point b (1,0);
 Le second argument est initialisé avec la valeur par défaut
 Ici, les objets sont transmis par copie à la fonction coincide
                                                        Christophe Collard
Remarques
 le principe d’encapsulation est-il violé ?
 a.coincide(b)
 l’objet « a » accède aux données privées de l’objet transmis « b »
 En C++, l’unité de protection est la classe et non l’objet.
 Si A et B sont 2 classes différentes, une fonction membre de A ne
 peut accéder aux données privées de B (sauf à la déclarer comme
 amie de la classe B – cf. plus tard)                 Christophe Collard
Transmission d’un objet par adresse



                                        a          x              y

                                                adresse      adresse


                                                 valeur       valeur




                                      b            x              y
                                      adpt
                                                adresse      adresse


                                                 valeur      valeur




                                               a.coincide (b)
                                             Christophe Collard
Attention aux effets de bord
 la transmission par adresse est efficace car les données ne sont
 pas dupliquées (gain de mémoire, gain de temps)

 les données de l’objet transmis ne sont pas protégées contre les
 modifications

 pour protéger les données de l’objet transmis de toute modification,
 on utilise le qualificatif const :

 dans la déclaration de la classe


 dans l’implémentation de la fonction



 les données de l’objet appelant sa fonction membre ne peuvent être
 protégées

                                                     Christophe Collard
   Transmission d’un objet par référence




     Les remarques précédentes sur les effets de bord restent valable
Attention : la transmission par valeur (copie) d’objets contenant des
variables allouées dynamiquement pose problème ! Christophe Collard
Retour d’un objet par une fonction
    par valeur
    par adresse
    par référence

la transmission d’objet par valeur ne fait qu’une copie partielle de l’objet
(attention aux objets contenant des pointeurs)

si une fonction retourne un objet par adresse ou par référence, il faut
éviter que l’objet retourné soit local (celui-ci étant détruit à la sortie de la
fonction !)




                                        retour incorrect (res est détruit à la
point& point::symetrique ();
                                        sortie de la fonction duplique)
                                                             Christophe Collard
   Auto-référence : le mot clé this
On peut avoir besoin d’utiliser l’adresse d’un objet ayant appelé une fonction




A l’intérieur de la méthode affiche, on ne connaît pas le nom de l’objet ayant
appelé cette fonction.
Quand on en a besoin, on peut y accéder grâce au mot clé this.
                                                             Christophe Collard
Les fonctions membres constantes
Rappel
  const int n = 20;
  La variable n est constante et n’évolue pas (calculée à la compilation)


On peut définir des objets constants
      Notion non triviale
      Les opérations sur les objets sont réalisées par ses méthodes.
                      L’utilisateur peut préciser les fonctions membres
                      autorisées à travailler avec des objets constants




                                                        Christophe Collard
     La méthode affiche est autorisée à travailler avec des objets constants.
     Elle peut modifier les valeurs d’un objet de type point.

     Il est possible de surdéfinir une fonction membre en se basant sur la
     présence ou non du qualificatif const.
      void affiche () const; // fonction 1      a.affiche(); appelle la fonction 1
Ex    void affiche ();       // fonction 2      c.affiche(); appelle la fonction 2
                                                              Christophe Collard
Construction, destruction et
   initialisation d’objets




                        Christophe Collard
Les objets automatiques & statiques
Durée de vie
 Les objets automatiques: créés par déclaration dans une fonction ou
 un bloc et détruits à la sortie de cette fonction ou de ce bloc.

 Les objets statiques: créés par déclaration en dehors de toute
 fonction ou dans une fonction avec le qualificatif « static ». Ils existent
 avant l’exécution de la fonction main et sont détruits a la fin de
 l’exécution du programme


Les objets temporaires
 Appel direct au constructeur d’une classe



              objet temporaire


                                                           Christophe Collard
    Exemple




    point (1,2);             appel direct au constructeur de la classe point


                                          objet temporaire
    a = point (1,2);         copie l’objet temporaire dans a
La copie fonctionne car par d’allocation dynamique de mémoire dans ‘’point’’
L’objet temporaire est détruit quand il n’est plus utilisé (ici a la fin du main)
                                                                Christophe Collard
Les objets dynamiques
Classes sans constructeur




déclaration d’un objet dynamique          point* adr;

allocation dynamique de mémoire           adr = new point;

réserve 2 emplacements mémoire pour stocker des données de type int

accès aux méthodes         adr -> initialise (1,3);     (*adr).initialise (1,3);
                           adr -> affiche ();           (*adr).affiche ();

destruction (explicite) de l’objet        delete adr;
                                                         Christophe Collard
Classes avec constructeur(s)




déclaration d’un objet dynamique     point* adr;

allocation dynamique de mémoire      adr = new point (1,2);

                                   appel au constructeur point (int, int)




                                                     Christophe Collard
Remarques

Lorsqu’il y a plusieurs constructeurs, l’opérateur new choisit le bon
constructeur grâce au nombre et/ou à la nature des arguments


S’il n’existe pas de constructeur ou s’il existe un constructeur sans
argument, new point; ou new point (); sont acceptés


Si tous les constructeurs possèdent au moins un argument, new point;
et new point (); sont rejetés




                                                        Christophe Collard
Le constructeur par recopie
Mise en évidence du problème




                               Christophe Collard
schéma de l’opération effectuée lors de l’appel de la méthode add
transmission de b par valeur
     b

    size


     p




           tableau dynamique de double

                                                  Christophe Collard
schéma de l’opération effectuée lors de l’appel de la méthode add
transmission de b par valeur                    copie des données de b dans v
     b                                    v
                                                      • copie de size (int)
    size                                 size         • copie p (pointeur)

     p                                    p




                                                       b.p et v.p pointent
                                                      sur le même tableau



           tableau dynamique de double

                                                             Christophe Collard
schéma de l’opération effectuée lors de la sortie de la fonction add
destruction de la copie v                       appel au destructeur
     b                                    v

    size                                 size
                                                  • libère v.size
     p                                    p       • libère le tableau situé en v.p




           tableau dynamique de double

                                                              Christophe Collard
retour au main
b.p ne pointe plus sur rien     fin du main ()
     b

    size
                              appel au destructeur
     p




                              • libère b.size
                              • libère le tableau situé en b.p


                               segmentation fault
                                                 Christophe Collard
   Solution                    b                                            v

                              size                                         size


                               p                                            p




 dupliquer le tableau de valeurs




 On définit un construteur par recopie (appelé automatiquement lors
 de la copie d’un objet) de la forme :

   vector (const vector&);      ou bien       vector (vector&);

En général, un constructeur par recopie n’a pas de raison de modifier l’objet
passé en argument. De plus, une fonction prévue pour un objet constant
peut toujours s’utiliser pour un objet non constant (réciproque fausse)
                vector (const vector&);                    Christophe Collard
Application




              etc …
                      Christophe Collard
   Résumé

La transmission par valeur d’un argument ou d’une valeur de retour d’une
fonction met en œuvre une recopie. Elle est réalisée soit:

      • par le constructeur de recopie par défaut (si aucun n’a été défini)
      • par le constructeur de recopie surdéfini dans la classe

      Lorsqu’un objet comporte des données dynamiques, il est
        indispensable de définir un constructeur par recopie



   On y indique comment dupliquer correctement les données de l’objet




                                                            Christophe Collard
Les tableaux d’objets
En C++ un tableau peut posséder des éléments de n’importe quels
types, y compris ceux définis par les utilisateurs via les classes




On peut déclarer un tableau « courbe » de points:
   point courbe [20];

Chaque élément du tableau peut accéder aux méthodes de sa classe :
   courbe[10].affiche();




                                                      Christophe Collard
Remarques

  • Un tableau d’objets n’est pas un objet
  • En POO pure, le concept de tableau d’objet n’existe pas
  • Il est toujours possible de définir une classe dont un des membres
  est un tableau d’objets

                   class courbe
                   { point p [20];
                      …..
                   }

Un constructeur par défaut est appelé pour chaque élément du tableau


         • soit la classe ne possède aucun constructeur
         • soit elle doit posséder un constructeur par défaut



                                                        Christophe Collard
Exemple




   point (7,0)       point (3,0)   point (11,0)   point (0,0)   point (0,0)




             tableau de 5 objets de type point




                                                                              Christophe Collard
Les tableaux dynamiques d’objets




création du tableau dynamique d’objets



         • soit la classe ne possède aucun constructeur
         • soit elle doit posséder un constructeur par défaut

destruction du tableau dynamique d’objets

     delete [ ] adcourbe;


indique qu’il s’agit d’un tableau d’objets
                                                        Christophe Collard
Objets membre
Une classe peut posséder des données membre qui soient définis
par l’utilisateur via une classe :




                                                   Christophe Collard
Les fonctions amies




                  Christophe Collard
    POO pure            Encapsulation des données



                        données membres privées accessibles seulement
                        par les méthodes publiques de la classe



                        une méthode d’une autre classe doit passer via les
                        méthodes publiques de la classe pour accéder aux
                        données privées


                        problème dans certains cas

    Exemple

On définit une classe vector et une classe matrix.
Produit matrice-vecteur nécessite l’accès aux données privées des 2 classes
                                                          Christophe Collard
Solutions

 • déclarer les données dans la partie public
 • utiliser des méthode publiques pour accéder aux données privées
 • arrêter le C++ et se remettre au fortran
 • utiliser des fonctions amies dans ses classes




                                                    Christophe Collard
Solutions

 • déclarer les données dans la partie public
 • utiliser des méthode publiques pour accéder aux données privées
 • arrêter le C++ et se remettre au fortran
 trop tard vu l’investissement déjà réalisé
 • utiliser des fonctions amies dans ses classes




                                                    Christophe Collard
Solutions

 • déclarer les données dans la partie public
 perte du bénéfice de l’encapsulation (protection des données)
 • utiliser des méthode publiques pour accéder aux données privées
 • arrêter le C++ et se remettre au fortran
 trop tard vu l’investissement déjà réalisé
 • utiliser des fonctions amies dans ses classes




                                                     Christophe Collard
Solutions

 • déclarer les données dans la partie public
 perte du bénéfice de l’encapsulation (protection des données)
 • utiliser des méthode publiques pour accéder aux données privées
 oui, mais pas toujours optimal pour protéger les données d’un objet
 • arrêter le C++ et se remettre au fortran
 trop tard vu l’investissement déjà réalisé
 • utiliser des fonctions amies dans ses classes




                                                     Christophe Collard
Il existe plusieurs situations d’amitié


• fonction indépendante amie d’une classe
• fonction membre d’une classe et amie d’une autre classe
• fonction amie de plusieurs classes
• toutes les fonctions membre d’une classe, amies d’une autre classe


Fonction indépendante amie d’une classe

Une fonction amie se déclare avec le mot clé friend


Exemple



                                                      Christophe Collard
Résultat   a et b coincident
           a et c ne coincident pas   Christophe Collard
Remarques
 ici les arguments de coincide sont transmis par valeur
 on pourrait les transmettre par référence

 l’emplacement de la déclaration d’amitié à l’intérieur de la classe
 n’a pas d’importance

 on ne peut pas utiliser d’argument implicite (this) dans une
 fonction amie, car elle n’appartient pas à la classe

 en général, une fonction amie possède 1 ou plusieurs arguments
 et/ou une valeur de retour du type de la classe ( qui justifie la
 déclaration d’amitié)

 quand une fonction amie retourne un élément du type de la
 classe, il est fréquent que ce soit un objet local à la fonction.
 La transmission doit alors s’effectuer par valeur.


                                                          Christophe Collard
Fonction membre d’une classe et amie d’une autre
  cas particulier de la situation précédente

      indiquer dans la déclaration d’amitié à quelle classe elle appartient
             utiliser l’opérateur de résolution de portée ::




 la fonction f appartient à la classe B           la fonction f accède aux
 la fonction f est amie de la classe A            données de A et B
                                                          Christophe Collard
Remarques
                      friend int B::f (char, A);


 le compilateur a besoin de connaître les caractéristiques de B pour
 compiler la classe A.
                            int f (char, A);

 le compilateur a besoin se savoir que la classe A existe, mais sans
 connaître ses caractéristiques.

                                                      Christophe Collard
Ecriture correcte du code




                            Christophe Collard
Fonction amie de plusieurs classes
 une fonction, qu’elle soit indépendante ou bien membre d’une classe
 peut faire l’objet de déclaration d’amitié dans plusieurs classes




 f peut accéder aux données privées de A et de B     Christophe Collard
Toutes les fonctions d’une classe sont amies d’une autre

  C’est la généralisation de la notion de fonction amie


  On pourrait déclarer toutes les fonctions d’une classe B comme
  amies d’une classe A, mais il est plus simple de le faire de
  manière globale dans la class A :




                                                          Christophe Collard
Une application de fonction amie indépendante




                                            Christophe Collard
Une application de fonction amie membre d’une classe




                                           Christophe Collard
La surdéfinition d’opérateurs




                        Christophe Collard
On considère une classe vector 2D :

 class vector
 { int x,y;
     …
 };

On définit 2 objets de type vector a et b

                       b



                           a


Peut on écrire comme pour un type standard C++ la somme a + b ?




                                                   Christophe Collard
Il faut surdéfinir l’opérateur + pour la classe
         définir une fonction operator + au sein de la classe



         utiliser le mot clé operator suivi de l’opérateur à surdéfinir



la fonction operator + peut être :
• soit une fonction membre de la classe
• soit une fonction indépendante amie de la classe
• soit une fonction indépendante de la classe


Afin de protéger les données et d’accélérer le code, on choisit en général
de surdéfinir l’opérateur comme fonction indépendante amie de la classe.


                                                          Christophe Collard
Surdéfinition d’opérateur avec une fonction amie




                                       Résultat
                                         coordonnees   (1,2)
                                         coordonnees   (2,5)
                                         coordonnees   (3,7)
                                         coordonnees   (6,14)



                                                Christophe Collard
Surdéfinition d’opérateur avec une fonction membre




                                  Résultat identique

                                              Christophe Collard
Remarques

   la fonction operator + est appelé de la manière suivante :

   fontion indépendante : a + b         operator + (a,b)

   fontion membre : a + b               a.operator + (b)

   la fonction membre operator + fait apparaître une dissymétrie et
   l’objet a ne peut pas être protégé

Opérateurs et transmission par référence
Dans les deux exemples précédents, on utilise la transmission par valeur

Pour des objets de grande taille, il vaut mieux utiliser la transmission
par référence. On peut alors protéger les objets transmis avec ‘’const’’
            point operator + (const point& a, const point&b)
Le retour de l’objet point se fait obligatoirement par valeur
                                                           Christophe Collard
Les opérateurs ++ et --




                       Résultat
                           a1 (3,6)
                           b (2,5)
                           a2 (3,6)
                           b (3,6)



            Christophe Collard
 Surdéfinition de l’opérateur =

   En l’absence de sudéfinition de l’opérateur =, il y a une simple recopie
   du 2nd opérande dans le 1er


         pose problème pour les objets contenant des pointeurs

                           a                                    b

 vector a(5), b;          size                                 size

 b = a;
                           p                                    p




cf. constructeur par recopie

                                 tableau dynamique de double

                                                                      Christophe Collard
Christophe Collard
Surdéfinition de l’opérateur [ ]
 exemple de la classe vector
             l’opérateur [ ] permet d’accéder au ième élément du vecteur

        En informatique on commence à compter à partir de 0
        En mathématiques on commence à compter à partir de 1


                 C’est l’opérateur [ ] qui fera la conversion



 C++ impose de définir l’opérateur [ ] comme fonction membre
                        int& operator [ ] (int);

 retour par référence obligatoire afin d’utiliser l’opérateur pour affecter
 des valeurs

                                                          Christophe Collard
Résultat   369


           Christophe Collard
Remarque
  L’opérateur [ ] ne peut pas être appliqué à un objet constant.
  Il aurait fallut le définir de la façon suivante

                    int& operator [ ] (int) const;




                                                     Christophe Collard
Surdéfinition des opérateurs new et delete
 La surdéfinition se fait obligatoirement par une fonction membre
 La fonction NEW reçoit un argument de type size_t (bibliothèque stddef)


                                  taille en octets de l’objet à allouer

 La fonction NEW renvoit un void* (adresse où est stocké l’objet)

 La fonction DELETE reçoit un pointeur en argument (adresse objet)
 La fonction ne renvoit rien (void)

 Remarques
 La surdéfinition de l’opérateur new implique la prise en charge de la
 gestion de la mémoire

 NEW et DELETE ne reçoivent pas d’argument implicite (this)

                                                          Christophe Collard
Christophe Collard
Résultat
  Action                                  Affichage
point a(3,5);                     ++ nombre total de points = 1
new point (1,3);                  ++ nombre total de points dynamiques = 1
appel implicite par new           ++ nombre total de points = 2
point b;                          ++ nombre total de points = 3
new point (2,0);                  ++ nombre total de points dynamiques = 2
appel implicite au constructeur   ++ nombre total de points = 4
appel implicite par delete ad1    -- nombre total de points = 3
delete ad1;                       -- nombre total de points dynamiques = 1
appel implicite par delete ad2    -- nombre total de points = 2
delete ad2                        -- nombre total de points dynamiques = 0
fin prog. destruction de a        -- nombre total de points = 1
fin prog. destruction de b        -- nombre total de points = 0
                                                         Christophe Collard
 Remarques

La surdéfinition des opérateurs NEW et DELETE n’a d’incidence que
sur les objets dynamiques

Que NEW soit surdéfini ou non, son appel est toujours implicitement
suivi de celui d’un constructeur

De même, DELETE fait appel implicitement à un destructeur
Il est toujours possible de définir les opérateurs NEW et DELETE de
manière globale

    déclarer NEW et DELETE comme fonctions indépendantes
                 appel à cet opérateur par tous les types (y compris
                 ceux de base du C++)
                      ex int* adi = new int; y fait appel
                 plus de possibilité d’appeler l’opérateur new prédéfini

                                                        Christophe Collard
Les patrons de fonctions
 Les patrons de classes




                      Christophe Collard
La surdéfinition de fonctions permet de donner un nom unique à plusieurs
fonctions réalisant un travail différent

La notion de patron est plus puissante et plus restrictive

Plus puissante
  on écrit une seule fois la définition d’une fonction pour que le compilateur
  puisse l’adapter automatiquement à n’importe quel type

Plus restrictive
  toutes les fonctions ainsi fabriquées ont la même définition et le même
  algorithme

But
  écrire une fonction qui soit valable quel que soit le type des arguments
  utilisés

                                                           Christophe Collard
Exemple
    int min (int a, int b)                double min (double a, double b)
    { return (a < b) ? a : b;             { return (a < b) ? a : b;
    }                                     }

    float min (float a, float b)          long int min (long int a, long int b)
    { return (a < b) ? a : b;             { return (a < b) ? a : b;
    }                                     }

                             etc …

On écrit la même fonction pour tous les types existant en C++
              c’est long, très long, très très long
              et en plus il faut le faire pour toutes les fonctions
              ça multiplie les lignes de code et rend le code illisible
              il faut compléter le code quand on définit ses propres classes

                                                            Christophe Collard
   On résout ce problème en utilisant les patrons de fonctions

           cette méthode est très puissante


Elle permet de définir des méthodes pour des types qui n’existent pas encore



                       fonction
     patron    type




       Résultat   min (n,p) = 4
                  min (x,y) = 2.5                          Christophe Collard
Application à un type classe




Remarque il suffit de donner un sens à l’opérateur < pour des objet de
         type point pour pouvoir utiliser min (sans rien ajouter !)
                                                      Christophe Collard
Généralisation et conversion




 Quel type retourne fct ?




                               Christophe Collard
Généralisation et conversion




 fct (n, x, p) int (conversion de float vers int pour x)
 fct (x, n, y) float (conversion de int vers float pour n)
 fct (n, p, q) int
 fct (n, p, x) erreur (ne pas laisser choisir le compilateur à votre place !)



                                                             Christophe Collard
Généralisation et conversion




 fct (n, x, p) int (conversion de float vers int pour x)
 fct (x, n, y) float (conversion de int vers float pour n)
 fct (n, p, q) int
 fct (n, p, x) erreur (ne pas laisser choisir le compilateur à votre place !)

Remarque dans fct, on peut initialiser des variables de type T ou U

                                                             Christophe Collard
exemple




          Christophe Collard
Surdéfinition des patrons




Remarque
 on peut transmettre des éléments de n’importe quel type aux fonctions
 grâce aux patrons


 les fonctions surdéfinies doivent avoir un nombre d’arguments différent
 afin d’éviter les ambigüités
                                                       Christophe Collard
 Les patrons de classes

 Mise en évidence du problème




Comment stocker des points avec des coordonnées int, float, double, … ?


                    Utiliser des patrons de classe




                                                       Christophe Collard
  La définition inline :



  La définition à l’extérieur de la classe :




          nom du patron
                                   nom de la fonciton
nom de la classe




                                                        Christophe Collard
Réécriture du code




                     Christophe Collard
Les flots




            Christophe Collard
les opérateurs << et >> assurent         le transfert de l’information

                                         le formatage de l’information

Un flot est un objet d’une classe prédéfinie :
ostream pour le flot de sortie
istream pour le flot d’entrée

Chacune de ces 2 classes surdéfinit les opérateurs << et >> pour les
différents types de base du C++ (fichier iostream)


Le flot cout est connecté à la sortie standard
Le flot cin est connecté à l’entrée standard




                                                           Christophe Collard
Surdéfinition des opérateurs << et >>




                                        Christophe Collard
La technique de l’héritage




                       Christophe Collard
  Le concept de l’héritage (ou de classes dérivées) constitue l’un des
  fondements de la POO

    Intérêt
Classe dérivée :
• nouvelle classe
                                                             classe de base
• définie à partir de la classe de base                    propriétés de la classe

• hérite des propriétés de la classe de base
• ajoute de nouvelles propriétés à la classe de base
• ne modifie pas la classe de base
                                                             classe dérivée
                                               propriétés classe de base + nouvelles propriétés



  permet de développer de nouveaux outils en se basant sur les acquis de
  la classe de base


                                                                    Christophe Collard
Remarque

 L’héritage n’est pas limité à un seul niveau
 • une classe dérivée peut devenir classe de base pour une autre classe
 • plusieurs classes peuvent être dérivées d’une même classe




                                                     Christophe Collard
Mise en œuvre de l’héritage
Classe de base




                              Christophe Collard
On ajoute une information à cette classe : la couleur du point

Classe dérivée




Programme principal




                                                        Christophe Collard
 Utilisation des membres d’une classe de base dans une
 classe dérivée

Quand on appelle p.affiche() pour un objet de type pointcol, cette fonction
n’est pas définie dans la classe enfant (pointcol)



C’est la fonction affiche de la classe parent (point) qui est appelée



C’est la fonction affiche de la classe parent (point) qui est appelée




                                                           Christophe Collard
 Utilisation des membres d’une classe de base dans une
 classe dérivée

Quand on appelle p.affiche() pour un objet de type pointcol, cette fonction
n’est pas définie dans la classe enfant (pointcol)



C’est la fonction affiche de la classe parent (point) qui est appelée



C’est la fonction affiche de la classe parent (point) qui est appelée


            Définir une méthode affichec () dans pointcol du type :




                                                           Christophe Collard
Problème :

 pointcol n’a pas accès aux données privées de point (x et y)

               soit mettre les données de point dans la partie protected

               soit utiliser une méthode publique de point




Surdéfinition des fonctions membre

  les fonctions affiche () et afficec () effectuent les même tâches
               leur donner le même nom (surdéfinition)


                                                         Christophe Collard
Christophe Collard
Appel des constructeurs et destructeurs




                                          Christophe Collard
Le constructeur par recopie




                              Christophe Collard
  Le contrôle des accès

  But :   protection des données de la classe de base

les données et méthodes privées sont inaccessibles en dehors leur classe

les données et méthodes publiques sont accessibles partout

     comment protéger les données de la classe de base et les rendre
     accessibles par la classe dérivée ?




                                                        Christophe Collard
  Le contrôle des accès

  But :   protection des données de la classe de base

les données et méthodes privées sont inaccessibles en dehors leur classe

les données et méthodes publiques sont accessibles partout

     comment protéger les données de la classe de base et les rendre
     accessibles par la classe dérivée ?

             définir les données et méthodes protégées




                                                         Christophe Collard
      Remarques
         les fonctions amies d’une classe dérivée possèdent les même droits
         que les fonctions membre

         la déclaration d’amitié ne s’hérite pas

            f : fonction amie de la classe A
                                                                                       f n’est pas amie de B
            B : classe dérivant de la classe A

         il est possible d’effectuer des dérivations différentes de public
                                            class B : public class A

           classe de base                         dérivée public            dérivée protected               dérivée private
statut initial   accès aux FMA   accès externe nouveau statut accès externe nouveau statut accès externe nouveau statut accès externe

public                                         public                       protected                    private
protected                                      protected                    protected                    private
private                                        private                      private                      private


                                                                                                     Christophe Collard
Utilisation

                          partie commune d’un problème
                                      classe de base




              dérivée 1        dérivée 2               dérivée 3     dérivée 4


          solution 1          solution 2         solution 3        solution 4


   gain de temps en programmation

   par de pénalité de temps pour les fonctions non utilisées dans la
   classe dérivée, car ne sont pas inclues lors de l’édition de lien

   perte de temps lors d’appel de fonctions imbriquées



                                                                         Christophe Collard
L’héritage multiple




                      Christophe Collard
Les espaces de nommage




                   Christophe Collard
Mot clé : namespace
 zones de déclaration permettant de délimiter la recherche des noms
 des identificateurs par le compilateur

But
 regrouper les identificateurs logiquement pour éviter les conflits de
 nom entre plusieurs parties d’un même projet

Remarque
 par défaut, C++ utilise un espace de nommage (namespace std) de
 portée globale dans lequel il doit y avoir aucun conflit de nom

Définition d’un espace de nommage




                                                        Christophe Collard
Remarque

  un namespace peut être découpé en plusieurs morceaux




      les identificateurs définis à l’intérieur d’un même namespace
      ne doivent pas entrer en conflit




                                                     Christophe Collard
Accès aux membres d’un namespace
   Il se fait grâce à l’opérateur de résolution de portée




Définition de fonctions d’un namespace



   La fonction peut aussi être implantée à l’extérieur du namespace
   en utilisant l’opérateur de résolution de portée
                                                            Christophe Collard
  On peut de même définir des classes dans un namespace

Définition d’un namespace dans un namespace




Alias de namespace
  Lorsqu’un namespace porte un nom compliqué, il peut-être
  avantageux de définir un alias
                 namespace nom_alias=nom;
                                                  Christophe Collard
La directive using
 elle permet d’utiliser tous les identificateurs d’un namespace sans
 spécifier cet espace devant chaque fonction ou variable




                                                       Christophe Collard

				
DOCUMENT INFO
Description: This is a document where you can start reading and learning about Programming Languages