---
# System prepended metadata

title: Cour 5 -- Language Orienté Objet avancé (C++)
tags: [M1 S1, cpp, cour]

---

# Cour 5 -- Language Orienté Objet avancé (C++)

###### tags `cour` `M1 S1` `cpp`
[Somaire](/V1WXmN9oTdauw8pTXPhqrQ)\
[Precedent](/xWa96-AGQI6G__rHTzd0Tg)
> [time= 12 oct 2020]

[TOC]

## association
### ordinaire
![](https://i.imgur.com/GZXjucR.png)
On peut faire de l'association ordinaire en utilisatant juste des pointeur vers notre objet en relation.
```cpp=
class Vol 
{
 private:
    Personne **passagers;
    int nPassagers;
 public:
    void prendUnPassagerEnPlus(Personne &);
    bool aPourPassager(const Personne &);
};

class Personne 
{
 private:
    Vol **vols;
    int nVols;
 public:
    void sEnregistreDansLeVol(Vol &);
    bool estPassagerDuVol(const Vol &);
};

void Personne::sEnregistreDansLeVol(Vol &leVol) 
{ 
    if (this->estPassagerDuVol(leVol)) 
        return; 
    add(vols,nvols,leVol); 
    leVol.prendUnPassagerEnPlus(*this);
}
void Vol::prendUnPassagerEnPlus(Personne &lePassager) 
{
    if (this->aPourPassager(lePassager)) 
        return; add(passagers,nPassagers,lePassager);
    lePassager.sEnregistreDansLeVol(*this);
}
```
### class d'association
Au lieu de mettre la relation dans les classe diretement.
On utilise une class externe, avec une méthod static.
![](https://i.imgur.com/PIJbeoH.png)

```cpp=
class Personne 
{
    void addVol(const Vol &v) 
    { 
        RelationVolPassager::add(v,*this); 
    }
};
class Vol 
{
    void addPassager(const Personne &p) 
    {
        RelationVolPassager::add(*this,p); 
    }
};
class RelationVolPassager {
  friend class Vol;
  friend class Personne;
  
  private:
    static void add(const Vol &,const Personne &);
};
 
```
## agrégation (simple)
On utilise une liste d'objet avec référence ou pointeur
![](https://i.imgur.com/pavvHXC.png)
```cpp=
class Evenement 
{};
class Historique 
{
private:
    const Evenement **lesEvenements;
    int nEvenement;
public:
    void addEvenement(const Evenement &);
    void removeEvenement(const Evenement &);
    Evenement *getEvenementAt(int);
...
};
```

## composition
On ajoute objet ou tableau d'objet un champ (sans pointeur ou référence)
![](https://i.imgur.com/plYAyoz.png)

```cpp=
class F3 {
  private:
    class Piece {};
    Piece pieces[3];
};
```

## généralisation / spécialisation
- généralisation vers le parent
- spécialisation vers l'enfant

```
          [    véhicule    ]
                  ^
généralisation    |     spécialisation
                  |
          [    voiture    ]
```


|   Conception   |      language       |
|:--------------:|:-------------------:|
|    relation    |       - champ       |
|    relation    | class d'association |
|                |                     |
| Spécialisation |      héritage       |
| Spécialisation |     délégation      |

## spécialisation
On peut utiliser l'héritage.
- on crée un héritage avec `class MaCall: public Parent`
- on peut **redéfinir** une méthode en la réecrivant
- pour récupéré une méthode de la classe du dessus on utilise le nom de la méthode `Parent::méthod`
- initialisation, on utilise les contructeur de la class parent dans la list d'initialisation (`super` en java est remplacé par le nom de la class)
    - attention a initialiser les class du dessus avant
- la destruction se fait dans le sens inverse

### redéfinition vs surcharge
:::success
**surcharge** dans le context on redéfini une meme fonction (en changeant le nombre d'argument ou les types) 
:::
```cpp=
class A 
{
  public:
    void m1(int i);
    void m1(char f); // surcharge
    void m2(int i);
    void m2(char c); // surcharge
};
```
:::success
**redifinition** on utilise un sybole déja utilisé
:::
```cpp=+
class B : public A {
 public:
   void m1(int i); //redéfinition dans B par rapport a A
   void m1(float f); //surcharge
};
```


## visibilité
rapelle:
- private
    - visible **uniquement** depuis les fonctions membres de la **classe**
- public
    - visible depuis **n’importe quelle partie du code**
- protected:
    - comme privé mais disponible dans les **dérivations**



| Protection dans la classe de base | accessibilité dans une fonction membre de la classe dérivée | Accessibilité dans une fonction amie de la sous- classe | Accessibilité par utilisation de la classe dérivée (hors cas précédents) |
|:---------------------------------:|:-----------------------------------------------------------:|:-------------------------------------------------------:|:------------------------------------------------------------------------:|
|            **private**            |                             :x:                             |                           :x:                           |                                   :x:                                    |
|           **protected**           |                     :white_check_mark:                      |                   :white_check_mark:                    |                                   :x:                                    |
|            **public**             |                     :white_check_mark:                      |                   :white_check_mark:                    |                                                                          |



toujours mettre les champs en privé
et mettre les methodes getter setter ne protected

## compatibilité des types
- on peut toujours convertir une instance d'une class donnée en un objet de sa super-classe
- on a de l'object slicing
```cpp=
class DeBase 
{...};
class SousClasse : public DeBase 
{...};
class BienEnDessous : public SousClasse 
{...};
int main() 
{
    BienEnDessous unObjet;
    DeBase unObjetDeBase = unObjet;
    //unObjet = unObjetDeBase; // strictly forbidden...
    
    BienEnDessous *p = &unObjet; 
    DeBase *p2;
    p2 = p;
    //p = p2; // formellement interdit
}
```


### liaison tardive (dynamique)
l’appel à une méthode qualifiée de virtuelle (`virtual`) provoquera à l’exécution la recherche de la méthode appropriée - late binding

C'est du polymorphisme par sous typage
```cpp=
class DeBase 
{
  public:
    virtual void f() 
    { 
        cout << “DeBase“ << endl; 
    }
};
class SousClasse : public DeBase 
{
  public:
    virtual void f() 
    {
        cout << “SousClasse“ << endl; 
    }
};
void uneFonction(DeBase &o)
{
    o.f(); 
}

int main() 
{
    SousClasse unObjet;
    unObjet.f();
    
    DeBase instanceDeBase = unObjet; 
    instanceDeBase.f();
    
    SousClasse *pSousClasse = &unObjet; 
    pSousClasse->f();
    
    DeBase *pBase = pSousClasse; 
    pBase->f();
    
    uneFonction(unObjet);
    return 0;
}
```

sortie:
```
SousClasse 
DeBase 
SousClasse 
SousClasse 
SousClasse
```


[suivant](/cGQPtmoaTZSwx3NaECxuHg)