next up previous contents
Next: Classes abstraites Up: Héritage Previous: Ambiguïtés

Liaison dynamique

La liaison dynamique est un mécanisme distinct (bien qu'étroitement lié) de l'héritage. C'est le fait qu'un nom de fonction membre d'une classe de base peut être associé à une fonction membre d'une classe dérivée.

class base{
public:
  virtual void vf1();
  virtual void vf2();
  virtual void vf3();
  void f();
}
class derivee: public base{
public:
  void vf1();     // redefinit vf1
  void vf2(int);  // cache base::vf2
  int vf3();      // interdit !!
  void f();
};
void essai(){
  derive d;
  base * bp = &d ; // ok conversion de pointeur
                   // derivee vers base
  bp->vf1();       // derivee::vf1() !!!
  bp->vf2();       // base::vf2()
  bp->f();         // base::f()
}

Ce mécanisme est essentiel dans la POO. Il permet de reléguer la réalisation d'une fonction membre à un descendant. C'est une forme de polymorphisme : grâce à la liaison dynamique, un même nom de fonction pourra correspondre à des réalisations différentes suivant les classes dérivées. Par exemple, une fonction virtuelle draw() membre d'une classe des formes sera définie pour chaque classe dérivée de la classe des formes. Par la liaison dynamique, un appel de cette fonction draw() sera associé suivant les cas à la fonction draw() de la classe dérivée sur laquelle pointe l'objet.

Ce mécanisme n'est pas un mécanisme de surcharge : ce n'est pas le type (statique) de l'objet qui permettra de déterminer quelle est la fonction draw() qui sera appelée, mais c'est à l'exécution, suivant l'affectation qui aura été réalisée sur le pointeur qui déterminera la fonction appelée.

Concrètement en C++, un client va utiliser un objet de type pointeur (ou une référence) vers la classe de base, ce pointeur pointant en fait vers un objet d'une classe dérivée (une implémentation particulière), la liaison dynamique fera que les bonnes fonctions (celles de l'implémentation) seront appelées.

Attention, tout ceci ne concerne que des références ou des pointeurs. Avec l'exemple précédent:

void essaibis(){
  derive d;
  base  bp = d ; // ok conversion 
                 // derivee vers base
  bp.vf1();      // base::vf1()
  bp->vf2();     // base::vf2()
  bp->f();       // base::f()
}





Mon Oct 20 14:02:48 MET 1997