# Cour 6 -- Language Orienté Objet avancé (C++)
###### tags `cour` `M1 S1` `cpp`
[Somaire](/V1WXmN9oTdauw8pTXPhqrQ)\
[Precedent](/xWa96-AGQI6G__rHTzd0Tg)
> [time= 19 oct 2020]
[TOC]
## héritage
### constructeur de copy
```cpp=
class A
{
public:
A() { cout << "A()" << endl; }
A(const A &a) { cout << "A(const A&)" << endl; }
};
class B : public A
{
public:
B() { cout << "B()" << endl; }
B(const B &b) :A(b){ cout << "B(const &B)" << endl; } // add explicit A(b)
};
void f(B unObjet)
{ }
int main()
{
B b;
cout << "Appel a f(B)" << endl; f(b);
return 0;
}
```
```shell=
$ ./main
A()
B()
Appel a f(B)
A(const A&) # apelle au constructeur de copy
B(const &B)
```
### sous-typage (héritage privé)
On peut faire une composition en faisant de l'hérigage privé.
Mais on préfaire **utiliser l'heritage simple**.
### composition classique
```cpp=
class Moteur
{
public:
void demarre() { ... };
};
class Voiture
{
private:
Moteur leMoteur;
public:
void demarre() { leMoteur.demarre(); }
};
```
### composition par hériage privé
```cpp=
class Moteur
{
public:
void demarre() { ... };
};
class Voiture : private Moteur
{
public:
void demarre() { Moteur::demarre(); }
}
```
### hériage protégé
Son usage est tres rare.

## factorisation
Quand on voit que des objet ont des méthode commune on factorise.
C'est un peut un mode d'emploie.

- On utilise des fleche avec des pointillé
- fleche pleine pour les relations entre interface en étend un autre
On crée donc une classe interface avec des virtuelle pure (`virtual method = 0;`).\
Ce qui est équivalent abstract en Java
## factorisation d'implémentation
On va faire apparaitre des class abstraite.
On peut spécifié `_impl` pour dire que c'est une classe d'implémentation.
```cpp=
class Individu
{
public:
virtual string donneTonNom()=0;
virtual void prononceTonNom()=0;
};
class _Individu : public Individu
{
private:
string nom;
protected:
void prononceTonNom(mode m)
{
synthétiseurVocal.setMode(m);
synthétiseurVocal.synthetise(donneTonNom());
}
public:
virtual string donneTonNom() { return nom; }
};
class Homme : public _Individu
{
public:
virtual void prononceTonNom()
{ prononceTonNom(GRAVE); }
};
class Femme : public _Individu {
public:
virtual void prononceTonNom()
{
prononceTonNom(AIGU);
}
};
```
## conversion polymorphe
- upcast (conversion vers le haut) `static_cast<type>()`
- objet
- pointeur
- référence
- dowcast (conversion vers le bas) `dynamic_cast<type>()`
- impossible sur les objet
- à controler sur les pointeurs
- à controler sur les reférence
`dynamic_cast<type>`:
- permet d’obtenir une conversion vers un sous-type (downcast)
- un pointeur nul (0) si la conversion n’est pas correcte
- une exception (bad_cast) si la référence n’est pas correcte
## RTTI
Pour faire du RTTI il faut laisser des types apres la compilation.
Utiliser souvent pour debug.
On utilise `typeid(type)` ou `typeid(expr)`.
On récupere un objet de type: `type_info`.
- On peut les comparé avec `==`
- On peut récupéré le nom de type avec la méthode `name`
- ce type n’est pas instanciable ni copiable
A utiliser **que pour debug**, on ne produit pas de code, avec du RTTI!
## Héritage multiple
### compostion multiple
On peut vouloir utiliser l'héritage multiple pour faire de la composition multiple.
Il vaut mieux utilisr la compostion simple.
#### par héritage multiple
```cpp=
class Magnetophone
{
public:
void demarreEcoute() { ... };
void demarreEnregistrement() { ... };
};
class Camera
{
public:
void demarreProjection() { ... };
void demarreEnregistrement() { ... };
};
```
```cpp=+
class Camescope : private Magnetophone, private Camera
{
public:
void enregistreFilm() {
Magnetophone::demarreEnregistrement();
Camera::demarreEnregistrement();
}
void regardeFilm() {
Magnetophone::demarreEcoute();
Camera::demarreProjection();
}
};
```
### version classique
**il vaut mieux utiliser cette méthode**
```cpp=+
class Camescope {
private:
Magnetophone m;
Camera c;
public:
void enregistreFilm()
{
m.demarreEnregistrement();
c.demarreEnregistrement();
}
void regardeFilm()
{
m.demarreEcoute();
c.demarreProjection();
}
};
```
### génélisation multiple
Exemple de d'objet avec un généralisation multiple:
- l'hornitorique
- l'hidravioon

```cpp=
class Imprimable
{
public:
virtual void imprimer()=0;
};
class Editable
{
public:
virtual void editer()=0;
};
class CourrierElectroniqueRecu : virtual public Imprimable
{
public:
virtual void imprimer() { /* just do it... */}
};
class DocumentPDF : virtual public Imprimable,
virtual public Editable
{
public:
virtual void editer() { /* do your best... */ }
virtual void imprimer() { /* merci Johannes Gensfleisch
* zur Laden zum Gutenberg */ }
};
```
### Probleme?
- Aucun problème théorique \
car on hérite de rien (ou presque), i.e. pas d’implémentation, tout est abstrait
- Seul problème pratique, l’éventuel **conflit de nom**
- deux super-types utilisent un même nom...
- si les actions sont différentes on a un probleme

```cpp=
class IPoint
{
public:
virtual void affiche() = 0;
};
class ICouleur
{
public:
virtual void affiche() = 0;
};
class PointColore : virtual public IPoint,
virtual public ICouleur
{
public:
virtual void affiche() { /* OK */ }
};
```
##### Construction en diamand
```cpp=
class Base {
public:
Base(int v) {}
};
class Classe1 : virtual public Base {
public:
Classe1() : Base(3) {} // N’est appelé que si la partie Base n’existe pas...
};
class Classe2 : virtual public Base {
public:
Classe2() : Base(5) {} // N’est appelé que si la partie Base n’existe pas...
};
class ToutEnBas : virtual public Base,
virtual public Classe1,
virtual public Classe2 {
public:
ToutEnBas() : Base(4), Classe1(), Classe2() {}
};
```
### le typage
Comme précédement.
Mais attention au dynamic_cast qui change les adresses.
Donc ne pas se fié au adresse comme identifiant
### conseil
- N’utilisez pas l’héritage multiple pour faire de la composition
- Réservez-le uniquement pour la généralisation multiple
- Déclarez toutes les méthodes virtuelles
- Déclarez tous les héritages comme virtuels
- Ne comptez plus sur l’adresse comme identifiant de l’objet
## surcharge d'opérateur
On peut surcharger quasiment tout les opérateur en c++;
[suivant](/NP4jzSxKSPy2sv9RsWcB2Q)