58 votes

Pourquoi avons-nous réellement besoin d'héritage privé ou protégé en C ++?

En C ++, je ne peux pas penser à un cas dans lequel je souhaiterais hériter d'une propriété privée / protégée d'une classe de base:

 class Base;
class Derived1 : private Base;
class Derived2 : protected Base;
 

Est-ce vraiment utile?

48voto

Luc Touraille Points 29252

Il est utile lorsque vous souhaitez avoir accès à certains membres de la classe de base, mais sans les exposer dans votre interface de classe. Privé de l'héritage peut être vu aussi comme une sorte de composition: le C++ faq lite donne l'exemple suivant pour illustrer cette affirmation

class Engine {
 public:
   Engine(int numCylinders);
   void start();                 // Starts this Engine
};

class Car {
  public:
    Car() : e_(8) { }             // Initializes this Car with 8 cylinders
    void start() { e_.start(); }  // Start this Car by starting its Engine
  private:
    Engine e_;                    // Car has-a Engine
};

Pour obtenir la même sémantique, vous pouvez également écrire la voiture de Classe comme suit:

class Car : private Engine {    // Car has-a Engine
 public:
   Car() : Engine(8) { }         // Initializes this Car with 8 cylinders
   using Engine::start;          // Start this Car by starting its Engine
};

Cependant, cette façon de faire présente plusieurs inconvénients:

  • votre intention est beaucoup moins clair
  • elle peut conduire à des abus de l'héritage multiple
  • il rompt l'encapsulation du Moteur de la classe, vous pourrez accéder à son protégé les membres de l'
  • vous êtes autorisé à remplacer le Moteur de méthodes virtuelles, qui est quelque chose que vous ne voulez pas que si votre objectif est une composition simple

40voto

Privé peut être utile dans pas mal de circonstances. L'un d'entre eux, ce sont des politiques:

Est partielle de la classe template de la spécialisation de la réponse à ce problème de conception?.

Une autre occasion où il est utile, c'est d'interdire la copie et de l'affectation:

struct noncopyable {
    private:
    noncopyable(noncopyable const&);
    noncopyable & operator=(noncopyable const&);
};

class my_noncopyable_type : noncopyable {
    // ...
};

Parce que nous ne voulons pas que l'utilisateur dispose d'un pointeur de type noncopyable* de notre objet, nous tirons privé. Ce qui compte, non seulement pour noncopyable, mais beaucoup d'autres classes de trop (politiques étant le plus commun).

15voto

Greg Rogers Points 18119

Modèles de patrimoine public IS-A.
Modèles d'héritage non publics IS-IMPLEMENTED-IN-TERMS-OF.
Modèles de confinement HAS-A, ce qui équivaut à IS-IMPLEMENTED-IN-TERMS-OF.

Sutter sur le sujet . Il explique quand vous voulez choisir un héritage non public sur un confinement pour les détails de la mise en œuvre.

3voto

Nemanja Trifunovic Points 17239

Par exemple, lorsque vous souhaitez réutiliser l'implémentation, mais pas l'interface d'une classe ET remplacez ses fonctions virtuelles.

3voto

Arkadiy Points 10567

Privé de l'héritage est principalement utilisé pour de mauvaises raisons. Les gens l'utilisent pour appliquer-EN-TERMES-DE, comme indiqué dans une précédente réponse, mais dans mon expérience, c'est toujours plus propre à conserver une copie plutôt que d'en hériter de la classe. Une précédente réponse, l'un sur les CBigArray, offre un parfait exemple de cet anti-modèle.

Je me rends compte qu'il peut y avoir des cas où a-a ne fonctionne pas en raison d'une trop zélé utilisation de "protégés", mais il est préférable de fixer le cassé de la classe que de casser une nouvelle classe.

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