Existe-t-il des exemples où nous avons *besoin* d'héritage protégé en C++ ?

StackOverflow https://stackoverflow.com/questions/31867

  •  09-06-2019
  •  | 
  •  

Question

Même si j'ai vu de rares cas où privé un héritage était nécessaire, je n'ai jamais rencontré de cas où protégé l'héritage est nécessaire.Quelqu'un a-t-il un exemple ?

Était-ce utile?

La solution

Les gens ici semblent confondre l'héritage de classe protégée et les méthodes protégées.

FWIW, je n'ai jamais vu personne utiliser l'héritage de classe protégée, et si je me souviens bien, je pense que Stroustrup a même considéré le niveau "protégé" comme une erreur en C++.Vous ne pouvez pas faire grand-chose si vous supprimez ce niveau de protection et comptez uniquement sur le public et le privé.

Autres conseils

Il existe un cas d’utilisation très rare d’héritage protégé.C'est là que vous souhaitez utiliser covariance:

struct base { 
    virtual ~base() {} 
    virtual base & getBase() = 0;
}; 

struct d1 : private /* protected */ base { 
    virtual base & getBase() { 
        return this; 
    } 
}; 

struct d2 : private /* protected */ d1 {
    virtual d1 & getBase () { 
        return this; 
    } 
}; 

L'extrait précédent tentait de masquer sa classe de base et de fournir une visibilité contrôlée des bases et de leurs fonctions, pour une raison quelconque, en fournissant une fonction « getBase ».

Cependant, cela échouera dans la structure d2, depuis d2 ne sait pas que d1 dérive de base.Ainsi, covariance ne fonctionnera pas.Un moyen de s'en sortir consiste à les protéger, de sorte que l'héritage soit visible dans d2.

Un exemple similaire d'utilisation de ceci est lorsque vous dérivez de std::ostream, mais je ne veux pas que des personnes aléatoires écrivent dans votre flux.Vous pouvez fournir un virtuel getStream fonction qui renvoie std::ostream&.Cette fonction pourrait préparer le flux pour la prochaine opération.Par exemple en mettant certains manipulateurs dedans.

std::ostream& d2::getStream() {
    this->width(10);
    return *this;
}

logger.getStream() << "we are padded";

FAQ C++ légère mentions d'un cas où le recours à l'héritage privé est une solution légitime (Voir [24.3.] Lequel dois-je préférer :composition ou héritage privé ?).C'est lorsque vous souhaitez appeler la classe dérivée depuis une classe de base privée via une fonction virtuelle (dans ce cas derivedFunction()):

class SomeImplementationClass
{
protected:
    void service() {
        derivedFunction();
    }

    virtual void derivedFunction() = 0;      

    // virtual destructor etc
};

class Derived : private SomeImplementationClass
{
    void someFunction() {
        service();
    }

    virtual void derivedFunction() {
        // ...
    }

    // ...
};

Maintenant, si vous souhaitez dériver de la classe Derived et que vous souhaitez utiliser Base::service() à partir de la classe dérivée (disons que vous souhaitez déplacer Derived::someFunction() à la classe dérivée), le moyen le plus simple d'y parvenir est de modifier l'héritage privé de Base à un héritage protégé.

Désolé, je ne peux pas penser à un exemple plus concret.Personnellement, j'aime rendre tout héritage public afin d'éviter de perdre du temps avec des discussions sur la question "dois-je rendre la relation d'héritage protégée ou privée".

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top