Optimisation - Polymorphisme “statique”

Décembre 2016

* Le polymorphisme est l'une des pierres angulaires du paradigme objet

En C++, il s'exprime sous la forme de fonctions virtuelles : celles-ci permettent d'adapter dynamiquement (i.e. à l'exécution) leur code au type de l'objet auxquelles elles sont appliquées. Cela peut avoir un impact négatif sur les performances, dans le cas particulier où :
  • le code à l'intérieur de ces fonctions est court ;
  • ces fonctions sont appelées très souvent.


En effet, comme le compilateur ne connaît pas à l'avance le code à appliquer, il ne peut pas appliquer les optimisations usuelles. Par ailleurs, le coût en place mémoire est d'autant plus grand que les branchements possibles (pour chaque type d'objet) sont nombreux.

Elle consiste à déclarer la classe parente comme classe générique, recevant comme paramètre le type de la classe dérivée. Cette classe devra ensuite tout déléguer à ses héritiers (comme un classe abstraite qui n'a que des fonctions virtuelles pures), mais ainsi le code à appliquer est connu au moment de la compilation.

Voici un petit exemple :
// classe de base paramétrée par le type de la classe dérivée
template<class TypeEnfant>
class Matrice {
public:
  // fonction de délégation
  TypeEnfant& CommeUnEnfant()
  {
    return (static_cast<TypeEnfant&>(*this));
  }

  // surcharge par délégation
  double operator()(int i, int j)
  {
    return (CommeUnEnfant()(i,j));
  }
private:
  ...
};

// exemples de classes dérivées
class MatriceTriangulaire : public Matrice<MatriceTriangulaire> {
private:
  ...
};

class MatriceSymetrique : public Matrice<MatriceSymetrique> {
private:
  ...
};

// fonction "virtuelle" fonctionnant avec n'importe quel type de matrice
template<class TypeEnfant>
double norme(Matrice<TypeEnfant>&);

// exemple d'application
double nt, ns;
MatriceTriangulaire mt;
MatriceSymetrique   ms;
nt = norme(mt);
ns = norme(ms);


N'empéche que ce n'est pas totalement souple, car tout ajout se fera dans la plupart des cas dans au moins deux endroits dans le code, dans l'interface de la classe dérivée et dans celle de la classe de base. Je préconise donc que cette méthode est à utiliser lorsque l'interface est figée et que comme le titre le dit, on veut optimiser le code.

A voir également :

Ce document intitulé «  Optimisation - Polymorphisme “statique”  » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.