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 signature correcte dans la fonction que nous remplaçons, et il semble que ce soit sa seule utilisation.
Cependant, dans le cas d'une fonction virtuelle pure, le compilateur lancerait une erreur si nous utilisions une signature incorrecte dans la classe Derived (ou la classe Base, selon la façon dont on voit les choses). Alors, est-il utile d'ajouter override
à la fin de la déclaration Derived::my_function()
?
Cependant, dans le cas d'une fonction virtuelle pure, le compilateur lancerait une erreur si nous utilisions une signature incorrecte dans la classe Derived
Non, cela compile:
class Base {
virtual void my_function() = 0;
};
class Derived : Base {
void my_function(int);
// ^^^ mistake!
};
Bien que cela ne:
class Base {
virtual void my_function() = 0;
};
class Derived : Base {
void my_function(int) override;
};
erreur:
void Derived::my_function(int)
marquéeoverride
, mais ne remplace pas
L'erreur dont vous parlez ne se produit que lorsque l'instanciation de Derived
- override
vous permet de détecter l'erreur plus tôt et rend la définition de Derived
plus claire/plus lisible.
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 du Base
décide que my_function
ne devrait plus être un pur virtuel, et aussi qu'il devrait prendre un nouveau paramètre. Avec override
en place, le compilateur détectera ce problème; sans override
votre classe Derived
continuerait de compiler.
Oui !!
Il améliore la clarté du code: override
le mot clé empêche l'ambiguïté et transmet sa signification de redéfinir sa méthode de classe de base.
Empêche une utilisation involontaire possible: À l'avenir, si la signature de la méthode de changement de classe de base (ici virtual
), elle force la classe dérivée à changer en conséquence. (avec erreur de compilation). Sinon (sans mot clé override
), il pourrait être considéré comme method overload
, ce qui n'est pas prévu.
Habituellement, ne pas se soucier de override
déplace simplement une erreur. Je trouve mieux l'emplacement où vous obtenez l'erreur - au point où vous définissez la méthode qui ne parvient pas à remplacer, plutôt que lorsque vous instanciez la classe.
Mais, il existe un moyen de se protéger contre un bogue 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 avons l'intention pour chaque foo
d'appeler son parent foo
. 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 nous obtenons une erreur de compilation.
Et oui, j'ai implémenté la fonction virtuelle pure Base::foo
.