1 conception et programmation à objets cours 6 mikal ziane précisions sur le polymorphisme le...

20
1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche ? Les méthodes virtuelles pures Complément : attributs et méthodes statiques Exercice (TD6)

Upload: adnet-soulie

Post on 03-Apr-2015

110 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

1

Conception et Programmation à Objets

Cours 6Mikal Ziane

Précisions sur le Polymorphisme

• Le problème à résoudre

• Les fonctions virtuelles

• Comment ça marche ?

• Les méthodes virtuelles pures

• Complément : attributs et méthodes statiques

• Exercice (TD6)

Page 2: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

2

Le Polymorphisme

• Idée: associer un même nom de méthode à plusieurs codes de méthode. Personne

afficher()

Enseignant Etudiant afficher()

• Si x est un objet le compilateur C++ peut déterminer à la compilation quelle fonction appeler lors de l'envoi du message x.afficher().• Le problème est plus difficile avec les pointeurs et références.•En effet un pointeur de Personne peut pointer sur un Etudiant sans que le compilateur le sache.

Page 3: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

3

int main (){ Personne* tab[2]; tab[0] = new Personne ("Alain", "Dupont"); tab[1] = new Etudiant ("Paul", "Dubois", 2); tab[0]->afficher(); // OK. cout << endl; tab[1]->afficher(); // n'affiche pas l'année // si afficher() pas virtuelle ! cout << endl; return 0;}Un pointeur sur une super-classe a un type statique (ici Personne*) et un type dynamique (Etudiant*, ou Enseignant*) selon le type de l'objet pointé.

Exemple

Page 4: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

4

Fonctions virtuelles

• Solution : on déclarera qu'afficher est une fonction virtuelle grâce au mot virtual.

• => mécanisme spécial pour appeler les méthodes : la liaison dynamique (dynamic binding, runtime dispatch, late binding).

• Le lien entre l'identificateur de la méthode et le code correspondant est fait dynamiquement (i.e. à l'exécution et non pas à la compilation).

• Une expression du genre p->afficher() déclenchera donc l'exécution de la méthode correspondant au type dynamique du pointeur p.

Page 5: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

5

Fonctions virtuelles (suite)

• Par prudence on déclarera toutes les méthodes virtual si une classe peut avoir des sous-classes.

• Ainsi avec les pointeurs et les références, mais pas avec les objets, c'est la méthode correspondant au code de l'objet pointé qui sera appelée.

• Piège: si dans une version on change la signature de la fonction virtuelle le mécanisme de virtual ne marche plus ! Le compilateur reconnaît les différentes versions grâce à leur signature (prototype) qui doit être identique.

Page 6: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

6

personne.hpp#include "chaine.hpp"class Personne {private: Chaine prenom_, nom_;public: Personne (char *p ="inconnu", char *n

="inconnu"); virtual void afficher() const; virtual const Chaine& prenom() const; virtual const Chaine& nom() const;};

• Si on met un const il faut le mettre dans les sous-classes aussi sinon le compilateur ne reconnaît pas la méthode !

Page 7: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

7

etudiant.hpp

#include "personne.hpp"

class Etudiant : public Personne {public:

int annee () const;Etudiant (char *p="inconnu", char *n="inconnu",

int annee =1);virtual void afficher () const;

private:int annee_;

};• Ici il faut absolument que le const soit présent (car il est présent pour Personne::afficher) sinon la signature d'afficher sera différente et le polymorphisme ne marchera pas !!

Page 8: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

8

Comment ca marche ?

void Personne::afficher () const

Alain

Dupont

void Etudiant::afficher () const

......

Paul

Dubois

2

Page 9: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

9

Comment ca marche ? (bis)

• Si une fonction est virtuelle dans une classe, les objets de cette classe (et des sous-classes) ont un champ supplémentaire.

• Ce champ pointe sur un tableau de pointeurs de méthodes de la classe de l'objet.

• Les versions de la même fonction virtuelle ont bien sûr le même numéro de poste dans tous les tableaux.

• Avec ce numéro il est alors facile d'appeler la bonne version de la fonction.

• Ainsi pe->afficher(); devient pe->vir[0]();

Page 10: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

10

Les méthodes virtuelles pures

• Il est possible de ne pas implémenter certaines méthodes d'une classe, en supposant que ce code sera défini dans les sous-classes !

• On dit alors que la méthode est virtuelle pure.

• Si une classe contient au moins une méthode virtuelle pure il est interdit de créer des objets de cette classe !

• Une classe qui n'aura jamais d'instance est dite abstraite sinon elle est dite concrète.

• Par contre rien n'interdit de définir des pointeurs vers une classe abstraite qui pointeront sur des objets des sous-classes.

Page 11: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

11

personne.hpp

#include "chaine.hpp"

class Personne {private: Chaine prenom_, nom_;public: virtual void afficher() const =0; virtual const Chaine& prenom() const; virtual const Chaine& nom() const;protected: Personne (char *p = "inconnu", char *n ="inconnu");};

Page 12: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

12

Création virtuelle• L'opérateur new et les constructeurs ne peuvent pas être virtuels.

• En effet on ne peut pas utiliser le type dynamique d'un objet qui n'existe pas encore !

• => Utiliser le pattern prototype quand c'est possible :

– Ajouter une fonction virtuelle clone()

– Créer à l'avance un prototype de chaque classe concrète

– Pour créer un objet : cloner le prototype de sa classe

Personne clone()

Enseignantclone()

Etudiantclone()

Page 13: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

13

Méthodes et champs statiques

• Un champ statique n'est pas stocké dans chaque objet mais une seule fois par classe. Sa durée de vie est la même que celles des variables globales.

• On ne peut donc pas initialiser un champs statique avec un constructeur: il y a une syntaxe spéciale à utiliser dans le .cpp.

• Un méthode statique n'a pas de pointeur this, elle ne peut donc utiliser que les champs statiques.

• Par contre elle n'a pas besoin d'un objet pour pouvoir être appelée ce qui est parfois indispensable.

• Exemple: on veut savoir combien il y a d'objets Personne qui existent à un instant donné.

Page 14: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

14

main.cpp (bis)

#include <iostream>using namespace std;

void main (){ Etudiant e ("Paul", "Dubois", 2); Personne p ("Alain", "Legoff"); Personne* pp = new Etudiant (); cout << "Il y a " << Personne::combien()

<< " personnes." << endl; delete pp; cout << "Il y a " << Personne::combien()

<< " personnes." << endl;}

Page 15: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

15

personne.hpp (bis)#include "chaine.hpp"

class Personne {private: Chaine prenom_, nom_; static int combien_;public: Personne (char *p = "nom inconnu",

char *n ="nom inconnu"); virtual ~Personne(); // oui virtual ! Virtual void afficher() const; virtual const Chaine& prenom() const; virtual const Chaine& nom() const; static int combien();};

Page 16: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

16

personnes.cpp (modifications)

int Personne::combien_ = 0;

Personne::Personne (char *p, char *n) : nom_ (n), prenom_ (p){ combien_++;}

Personne::~Personne (){ combien_--;}

int Personne::combien (){ return combien_; }

Page 17: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

17

Exercice (TD6)

• On veut à terme écrire un programme simulant le comportement de robots dans un plan (coordonnées x,y). Le décor dans lequel les robots évolueront sera constitué d'objets fixes ou eux-mêmes mobiles comme les robots.

• On commencera par un prototype extrêmement simple avec un robot, un trésor et une bombe, seul le robot étant mobile.

Page 18: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

18

• La simulation consiste à afficher à chaque tic d'une horloge imaginaire la position des objets mobiles, ici seulement le robot.

• A chaque tic de cette horloge les objets mobiles se déplacent en sautant selon leur vecteur vitesse (dx,dy par unité de temps).

Page 19: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

19

• Lorsqu'un objet mobile rencontre un objet fixe il se produit une action dépendant, pour ce prototype, uniquement de l'objet fixe.

• Cette action sera constituée de l'affichage d'un message ("boom !" pour la bombe, "bingo !" pour le trésor) ainsi que l'affichage de l'objet fixe responsable.

Page 20: 1 Conception et Programmation à Objets Cours 6 Mikal Ziane Précisions sur le Polymorphisme Le problème à résoudre Les fonctions virtuelles Comment ça marche

20

• Une action peut aussi se poursuivre en fonction du comportement souhaité pour l'objet fixe.

• Par exemple une bombe pourra interrompre la simulation alors qu'un trésor laissera la simulation continuer.

• Pour afficher un objet, fixe ou mobile, on affichera le symbole de l'objet (un caractère quelconque) et ses coordonnées.