105 votes

Écraser en toute sécurité C++ des fonctions virtuelles

J'ai une classe de base avec une fonction virtuelle et je veux remplacer cette fonction dans une classe dérivée. Est-il possible de faire le compilateur de vérifier si la fonction que j'ai déclaré dans la classe dérivée en fait remplace une fonction dans la classe de base? Je voudrais ajouter un peu de macro, ou quelque chose qui s'assure que je n'ai pas accidentellement déclarer une nouvelle fonction, au lieu d'annuler l'ancien.

Prenez cet exemple:

class parent {
public:
  virtual void handle_event(int something) const {
    // boring default code
  }
};

class child : public parent {
public:
  virtual void handle_event(int something) {
    // new exciting code
  }
};

int main() {
  parent *p = new child();
  p->handle_event(1);
}

Ici, parent::handle_event() est appelée à la place de child::handle_event(), parce que l'enfant de la méthode manque l' const déclaration et, par conséquent, déclare une nouvelle méthode. Cela pourrait aussi être une faute de frappe dans le nom de la fonction ou de légères différence dans les paramètres de types. Il peut aussi facilement se produire si l'interface de la base de changements de classe et de quelque classe dérivée n'était pas mis à jour pour refléter le changement.

Est-il un moyen pour éviter ce problème, je peux en quelque sorte dire au compilateur ou un autre outil pour vérifier cela pour moi? Tout utile drapeaux du compilateur (de préférence pour g++)? Comment voulez-vous éviter ces problèmes?

94voto

hirschhornsalz Points 16306

Depuis que g++ 4.7 il n'comprendre le nouveau C++11 override mot-clé:

class child : public parent {
    public:
      // force handle_event to override a existing function in parent
      // error out if the function with the correct signature does not exist
      virtual void handle_event(int something) override;
};

20voto

Charles Bailey Points 244082

Quelque chose comme C#' override mot-clé n'est pas une partie de C++.

Dans gcc, -Woverloaded-virtual met en garde contre le masquage d'une classe de base virtuelle de la fonction avec une fonction de même nom mais suffisamment différente de la signature qu'il n'a pas le remplacer. Il n'est pas, cependant, de vous protéger contre le défaut de remplacer une fonction en raison de la faute d'orthographe du nom de la fonction elle-même.

18voto

Ray Hidayat Points 7961

Autant que je sache, ne pouvez-vous pas juste faire de l'abstrait?

class parent {
public:
  virtual void handle_event(int something) const = 0 {
    // boring default code
  }
};

J'ai pensé que j'ai lu sur www.parashift.com que vous pouvez réellement mettre en œuvre une méthode abstraite. Ce qui fait sens pour moi personnellement, la seule chose qu'il fait, c'est la force des sous-classes pour la mettre en œuvre, personne n'a rien dit à ce sujet n'étant pas autorisés à avoir une mise en œuvre elle-même.

11voto

Doug Points 4923

Dans MSVC, vous pouvez utiliser le CLR override mot-clé, même si vous n'êtes pas de la compilation pour le CLR.

Dans g++, il n'y a pas de moyen direct de faire valoir que, dans tous les cas; d'autres ont donné de bonnes réponses sur la façon de prendre la signature des différences à l'aide de -Woverloaded-virtual. Dans une future version, quelqu'un pourrait ajouter une syntaxe comme celle - __attribute__ ((override)) ou l'équivalent de l'aide de C++0x syntaxe.

9voto

bobobobo Points 17477

Dans MSVC++, vous pouvez utiliser le mot-clé override

 la classe de l'enfant : public parent {
public:
 virtual void handle_event(int) remplacer{
 // nouveau code
}
};

override fonctionne à la fois pour la maternelle et du code CLR de MSVC++.

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