147 votes

Méthode virtuelle privée en C ++

Quel est l'avantage de rendre une méthode privée virtuelle en C ++?

J'ai remarqué cela dans un projet open source C ++:

 class HTMLDocument : public Document, public CachedResourceClient {
private:
    virtual bool childAllowed(Node*);
    virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
};
 

142voto

Prasoon Saurav Points 47488

Herb Sutter a très bien expliqué ici.

La ligne directrice n ° 2: Préférez faire des fonctions virtuelles privé.

Cela permet aux classes dérivées de surcharger la fonction pour personnaliser le comportement en tant que de besoin, sans exposer les fonctions virtuelles directement en les rendant exigible par les classes dérivées (comme ce serait possible si les fonctions étaient juste protégé). Le point est que les fonctions virtuelles existent pour permettre la personnalisation; à moins qu'ils ont aussi besoin d'être invoquée directement dans les classes dérivées de code, il n'y a pas besoin de toujours faire quelque chose, mais privé

73voto

sth Points 91594

Si la méthode est virtuelle, elle peut être remplacée par des classes dérivées, même si elle est privée. Lorsque la méthode virtuelle est appelée, la version remplacée est appelée.

(Contrairement à Herb Sutter cité par Prasoon Saurav dans sa réponse, la FAQ C ++ Lite recommande de ne pas utiliser de virtual virtuel , principalement parce que cela confond souvent les gens.)

11voto

Pooven Points 324

J'ai trouvé ce concept lors de la lecture de Scott Meyers Effective C++, Point 35: Envisager des solutions de rechange à des fonctions virtuelles. Je voulais référence Scott Mayers, pour d'autres qui pourraient être intéressés.

Il fait partie de la Méthode de Modèle de Modèle grâce à la Non-Interface Virtuelle idiome: le public face à des méthodes ne sont pas virtuel, mais plutôt d'envelopper la méthode virtuelle appels qui sont privés. La classe de base peut alors exécuter la logique avant et après le privé virtuel appel de la fonction:

public:
  void NonVirtualCalc(...)
  {
    // Setup
    PrivateVirtualCalcCall(...);
    // Clean up
  }

Je pense que c'est un très intéressant modèle de conception, et je suis sûr que vous pouvez voir comment le contrôle est utile.

  • Pourquoi faire de la fonction virtuelle private? La meilleure raison est que nous avons déjà fourni un public face à la méthode.
  • Pourquoi ne pas simplement le faire protected afin que je puisse utiliser la méthode pour d'autres choses intéressantes? Je suppose que cela dépendra toujours de votre conception, et comment vous croyez que la classe de base s'inscrit dans. Je dirais que la classe dérivée maker devrait se concentrer sur la mise en œuvre de la logique nécessaire; tout le reste est déjà pris en charge. Aussi, il y a la question de l'encapsulation.

À partir d'un C++ point de vue, il est tout à fait légitime pour remplacer un privé virtuel méthode, même si vous ne serez pas en mesure d'appeler à partir de votre classe. Cela prend en charge la conception décrite ci-dessus.

6voto

Jagannath Points 2326

La virtualité traite très bien ce sujet.

4voto

Zack Yezek Points 134

- Je les utiliser pour permettre aux classes dérivées pour "combler les vides" pour une classe de base sans s'exposer à de tels trous pour les utilisateurs finaux. Par exemple, j'ai très dynamique des objets provenant d'une base commune, qui ne peut mettre en œuvre des 2/3 de l'ensemble de la machine d'état (les classes dérivées de fournir le 1/3 restant, selon un argument de modèle, et la base ne peut pas être un modèle pour d'autres raisons).

J'ai BESOIN d'avoir la classe de base commune afin de faire beaucoup de l'Api publiques de fonctionner correctement (je suis en utilisant variadic templates), mais je ne peux pas laisser cet objet dans la nature. Pire, si je laisse les cratères de la machine d'état, sous la forme de fonctions virtuelles pures - n'importe où, mais dans le "Privé", je laisse un savant ou ignorant, l'utilisateur découlant de l'un de ses enfants des classes de remplacer les méthodes que les utilisateurs ne doivent jamais se toucher. Alors, j'ai mis la machine d'état 'cerveaux' en PRIVÉ des fonctions virtuelles. Puis les enfants immédiats de la classe de base de remplir les blancs sur leur NON-virtuel remplace, et les utilisateurs peuvent utiliser en toute sécurité les objets ou créer leurs propres classes dérivées sans se soucier de perturber le fonctionnement de la machine d'état.

Comme pour l'argument que vous ne devriez pas AVOIR de public de méthodes virtuelles, je dis BS. Les utilisateurs peuvent mal l'emportent sur les virtuals aussi facilement que celles du public - qu'ils sont de définir de nouvelles classes, après tout. Si le public ne devrait pas modifier une API, ne pas en faire virtuel À TOUS de rendre accessible au public des objets.

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