vendredi 17 août 2012

Explicit virtual overrides

class A
{
  virtual void f() const;
};

class B
{
  void f();
};

Regardons le code d'un peu plus près. Le "const" manquant dans la deuxième classe, est-ce voulu, ou est-ce une erreur du programmeur? La fonctionnalité C++11 "explicit virtual overrides" ajoute des mot-clés au langage pour permettre de spécifier très précisément le type d'héritage désiré. Démarrons sans plus attendre.

override

Le mot-clé override indique que la méthode doit absolument hériter, le compilateur jettera donc une erreur si ce n'est pas le cas. Par exemple:

class A
{
  virtual void f();
};

class B : public A
{
  virtual void f() override;
};

class C : public A
{
  virtual void f() const override;
};

La déclaration de f dans la classe C provoque l'erreur suivante: error: ‘virtual void C::f() const’ marked override, but does not override. Facile!

final

Le mot-clé final, bien connu des javaistes et attendu depuis longtemps du côté C++, peut s'appliquer soit à une classe, soit à une méthode. Dans le premier cas, le compilateur interdira d'hériter de la classe, alors que dans le second, il interdira l'héritage de la méthode.

class A
{
  virtual void f() final;
};

class B final : public A
{
  virtual void g();
};

class C : public A
{
  virtual void f() override;
};

class D : public B
{
};

La définition de la méthode f dans la classe C provoque le message d'erreur suivant: error: overriding final function ‘virtual void A::f()’, indiquant que la classe f a été marquée finale dans une classe parente. La définition de la classe D provoque l'erreur suivante: error: cannot derive from ‘final’ base ‘B’ in derived type ‘D’, indiquant que la classe D tente de dériver d'une classe finale.

Voilà des fonctionnalités qui vont, je l'espère, d'éviter beaucoup de maux de tête. En indiquant clairement au niveau de la classe parente quelles méthodes ne peuvent être héritées, et en indiquant clairement dans la classe fille les méthodes qui viennent d'une classe de base, l'on documente le comportement attendu de ses objets en laissant le compilateur en faire la vérification.

Cependant, l'exercice a ses limites: contrairement au const qui a un côté viral en forçant tous les types associés à être const-corrects, les mot-clés d'héritage peuvent être utilisés autant ou aussi peu que le programmeur le souhaite. Il faudra donc s'assurer qu'au niveau d'un projet, tout le monde suit le même standard, sinon le remède risque d'être pire que le mal: un programmeur pourra être persuadé que le code est faux car il manque un override, alors que l'auteur avait simplement décidé de l'ignorer.

Aucun commentaire: