# 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)