46 votes

Y a-t-il un intérêt à utiliser `override` lors du remplacement d'une fonction virtuelle pure?

Par exemple :

class Base {
  virtual void my_function() = 0;
};

class Derived : Base {
  void my_function() override;
};

D'après ce que j'ai lu, le mot-clé override est utilisé pour s'assurer que nous avons la bonne signature dans la fonction que nous sommes en train de remplacer, et il semble que ce soit son seul usage.

Cependant, dans le cas d'une fonction virtuelle pure, le compilateur lèverait une erreur si nous utilisions une mauvaise signature dans la classe dérivée (ou la classe de base, selon la perspective). Donc, est-ce qu'il y a un intérêt à ajouter override à la fin de la déclaration de Derived::my_function() ?

76voto

Vittorio Romeo Points 2559

Cependant, dans le cas d'une fonction virtuelle pure, le compilateur générerait une erreur si nous utilisions une signature incorrecte dans la classe dérivée

Non, ceci compile :

class Base {
  virtual void my_function() = 0;
};

class Derived : Base {
  void my_function(int);
//                 ^^^ erreur!
};

Tandis que ceci ne compile pas :

class Base {
  virtual void my_function() = 0;
};

class Derived : Base {
  void my_function(int) override;
};

erreur : void Derived::my_function(int) marqué override, mais ne remplace pas


L'erreur dont vous parlez se produit uniquement lors de l'instanciation de Derived - override vous permet de repérer l'erreur plus tôt et rend la définition de Derived plus claire/lisible.

31voto

dasblinkenlight Points 264350

Oui, c'est une bonne idée d'utiliser le mot-clé override de manière cohérente comme pratique défensive.

Envisagez une refonte lorsque l'auteur de la classe de base Base décide que la fonction my_function ne devrait plus être virtuelle pure et qu'elle devrait également prendre un nouveau paramètre. Avec l'utilisation de override, le compilateur détectera ce problème; sans override, votre classe Derived continuerait à être compilée.

7voto

JharPaat Points 115

Oui !!

Il améliore la clarté du code : override le mot-clé empêche l'ambiguïté et transmet son sens de remplacement de la méthode de sa classe de base.

Empêche une utilisation non intentionnelle possible : À l'avenir, si la classe de base modifie la signature de la méthode (ici virtual), cela oblige la classe dérivée à changer en conséquence (avec une erreur de compilation). Sinon (sans le mot-clé override), cela pourrait être considéré comme une surchage de méthode, ce qui n'est pas voulu.

3voto

Yakk Points 31636

En général, ne pas se soucier de override déplace simplement une erreur ailleurs. Je trouve qu'il est préférable de savoir où l'erreur se produit - au moment où vous définissez la méthode qui échoue à remplacer, plutôt que lorsque vous instanciez la classe.

Cependant, il existe un moyen d'utiliser cela pour protéger contre une erreur d'exécution.

struct Base {
  virtual void foo(int x = 0) = 0;

  void foo(double d) {
      foo( (int)d );
  }
};
inline void Base::foo(int x) { std::cout << "Default foo(" << x << ")\n"; }

struct Derived:Base {
  using Base::foo;
  virtual void foo() { // oops, no int!
    std::cout << "Derived::foo()\n";
    Base::foo();
  }
};
struct Derived2:Derived {
  virtual void foo(int x=0) override {
    std::cout << "Derived2::foo()\n";
    Derived::foo(x);
  }
};

ici, nous voulons que chaque foo appelle son foo parent. Mais parce que Derived::foo ne remplace pas la même signature que Base::foo, il n'est pas invoqué.

Ajoutez override après foo() dans Derived et vous obtiendrez une erreur de compilation.

Et oui, j'ai mis en œuvre la fonction virtuelle pure Base::foo.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X