// Héritage // ======== // Classe de base pour une personne class Person { private: string firstname; string lastname; public: int age; string toString() { ... } void message(string msg); }; // Classe pour un formulaire // On n'utilise pas la dérivation car // un formulaire "n'est pas" une personne class Form { public: Person person; Adress address; string toString() { return person.toString() + "@" + address.toString(); } }; Form form; foo(form.person.firstname); // Non car prive foo(form.person.age); // Mauvais class Student { Person person; int no; ... Student(string first, string last, int n = 0) : person(first, last), no(n) { ... } } // Utilisation de l'héritage car un étudiant -*-est-*- une personne class Student : public Person { int no; ... Student(string first, string last, int n) : Person(first, last), no(n) { ... } } Form fo; fo.message("hello"); // Impossible Student st; st.message("Hello"); foo(st.firstname); // Non car prive st.age = 37; // Qualificatifs : public, protected, private // ------------------------------------------- class Prof : private Person { public: Office off; ... }; Prof prof; prof.message("Hello"); // Non car message est private dans Prof prof.firstname; // Non prof.off = newoffice; // Dérivations class Personnel : public Person { ... }; class Prof : public Personnel { ... }; class Admin : public Personnel { ... }; class Guru { ... }; class ProfGuru : public Prof, public Guru { ... } // Constructeurs et destructeurs // ----------------------------- Conversions ----------- Dérivéee -> Base Student st("Charlie", "Brown"); Person p; p = st; Pointeurs Student *stp = new Student("Charlie", "Brown"); Person *pp; if (...) pp = stp; else pp = new Person(); void bar(Person *p) { p->message(); } bar(pp); bar(stp); class Figure { ... double surface(); double perimetre(); void draw() { cout << 1; } }; class ColorFigure : Figure { Color c; // Redéfinition : même prototype (nom, type des paramètre et type de retour) void draw() { cout << 2; } } Figure f; f.draw(); // 1 ColorFigure cf; cf.draw(); // 2 f = cf; f.draw() // 1 Figure *fp = &f; f->draw(); // 1 ColorFigure *cfp = &cf; cfp->draw(); // 2 cfp = &f; // Conversion impossible fp = &cf; fp->draw(); // 1 // Méthodes virtuelles : virtual la éthode appelée dépend du type dynamique class Figure { ... double surface(); double perimetre(); virtual void draw() { cout << 1; } }; class ColorFigure : Figure { Color c; // Redéfinition : même prototype (nom, type des paramètre et type de retour) void draw() { cout << 2; } } Figure f; f.draw(); // 1 ColorFigure cf; cf.draw(); // 2 f = cf; f.draw() // 1 Figure *fp = &f; f->draw(); // 1 ColorFigure *cfp = &cf; cfp->draw(); // 2 cfp = &f; // Conversion impossible fp = &cf; fp->draw(); //2 CHANGEMENT void foo(Figure *fp) { fp->draw(); // 1 et 2 } foo(&f) foo(&cf;) // Fonction virtuelle pures class Figure { virtual double surface() = 0; virtual draw() = 0; } class Square : Figure { double surface() { return width * height; } vois draw() { ... } private: double : width; double : height; }; class Disc : Figure { double surfacce() { return radius * 2 * PI } void draw() { ... } private double radius; const double PI = 3.14; } void foo(Figure *fp) { cout << fp->surface(); } Disc d(5); foo(&d); Vector v;