7
votes

Avertissement pour le mot clé virtuel manquant

J'ai eu un problème frustrant récemment qui a fait bouillir une erreur de codage très simple. Considérez le code suivant:

#include <iostream>

class Base
{
public:
    void func() { std::cout << "BASE" << std::endl; }
};

class Derived : public Base
{
public:
    virtual void func() { std::cout << "DERIVED" << std::endl; }
};

int main(int argc, char* argv[])
{
    Base* obj = new Derived;
    obj->func();
    delete obj;

    return 0;
}


1 commentaires

Supprimer dans l'exemple ne peut pas détruire dérivé car base n'a pas de virtuel destructeur


3 Réponses :


5
votes

Dans Visual C ++, vous pouvez utiliser l'extension de remplacement . Comme ceci: xxx

Cela donnera une erreur si la fonction ne remplace pas la méthode de la classe de base. J'utilise ceci pour toutes les fonctions virtuelles. Généralement, je définis une macro comme ceci: xxx

afin que je puisse l'utiliser comme ceci: xxx

J'ai regardé Pour quelque chose comme ça dans g ++ mais ne pouvait pas trouver de concept similaire.

La seule chose que je n'aime pas à ce sujet dans Visual C ++ est que vous ne pouvez pas avoir le compilateur le besoin (ou au moins avertir) sur toutes les fonctions remplacées.


3 commentaires

J'utilise cela aussi. Il est également pratique lorsque quelqu'un change la signature d'une fonction (ajout d'un paramètre, etc.) mais ne parvient pas à mettre à jour la ou les contreparties de base ou dérivées. Normalement, la virtuelle cesserait de fonctionner silencieusement, mais cette astuce rend le compilateur générer une erreur.


Super! Je ne savais pas à propos de cette extension. Je vais probablement utiliser cela pour mes propres projets depuis que j'utilise Visual Studio, mais pour ce projet particulier, je vais devoir coller à g ++ :(


Veuillez noter que remplacer est en C ++ 11, de sorte que fonctionnent avec le gcc et la cliquet récentes en mode C ++ 11 ( -std = c ++ 11 )



3
votes

Je ne connais aucun drapeau G ++ pour produire un avertissement à ce sujet (de ne pas dire qu'il n'y en a pas), mais je dirais que c'est une assez rare erreur. La plupart des gens écrivent d'abord la classe de base, en tant qu'interface utilisant des fonctions virtuelles pures. Si vous aviez dit: xxx

alors vous obtiendrez une erreur de syntaxe.


0 commentaires

1
votes

homme GCC

-Hoveroaded-virtuel (C ++ et Objective-C ++ uniquement) Avertissez quand une déclaration de fonction cache des fonctions virtuelles d'une classe de base. Par exemple, dans: xxx


1 commentaires

L'utilisation de cette option ne prévoit pas le code affiché ci-dessus. Dans ce cas, FOO :: FUNC n'est pas virtuel (qui est une condition préalable à l'avertissement), et même si c'était, il ne déclencherait toujours pas l'avertissement car :: Func correspond à la bonne signature. Si j'ai fait FOO :: FUNC Virtual et Changé Bar :: Signature de Func (c'est-à-dire FUNC (INT)) uniquement alors le déclencheur d'avertissement. Dans mon cas, je remplace une fonction non virtuelle de FOO, ce qui signifie que si j'ai une FOO * alors la mise en œuvre de la FOO sera appelée et non la mise en œuvre de la barre. Cependant, seulement si j'ai une barre * sera appelée la mise en œuvre de la barre.