mercredi 2 octobre 2013

Inheriting Constructors

Avec g++4.8 qui vient de débarquer dans Debian Jessy, c'est l'occasion de se pencher sur les nouveautés C++11 de cette version du compilateur. On a vraiment l'impression que l'on racle les tiroirs du standard, parce qu'il ne manquait quand même pas grand chose. Cependant, une fonctionnalité intéressante débarquant dans 4.8 est la possibilité d'hériter un constructeur.

L'idée est qu'il est fréquent que les constructeurs d'une classe fille se contentent de passer leurs arguments à la classe mère. Dans ce cas, pourquoi s'embêter à re-déclarer le constructeur? En utilisant le mot-clé using, l'on peut donc tirer le constructeur dans la classe fille. Voyons donc un exemple.

#include 
#include 

class A
{
public:
  A(std::string a):
    _a(std::move(a))
  {
  }
  
private:
  std::string _a;
};

class B : public A
{
public:
  B(std::string b):
    A(std::move(b))
  {
  }
};

int main()
{
  B b("abc");
}

Rien de bien compliqué. Notez tout de même l'utilisation du passage par valeur du paramètre et du std::move, qui optimisent le cas où la valeur peut être déplacée. Eh bien, avec l'héritage de constructeurs, B devient simplement:

class B : public A
{
  using A::A;
};

Et ça marche exactement de la même manière. L'on imagine bien qu'avec un constructeur de classe de base prenant de nombreux paramètres, c'est beaucoup de code que l'on peut ainsi économiser.

Si A a plusieurs constructeurs, ils sont tous hérités (sauf le constructeur par copie et le constructeur par défaut, qui suivent les règles habituelles). Il est cependant possible de redéfinir un constructeur dans B avec la même signature, qui sera prioritaire sur les constructeurs hérités.

Aucun commentaire: