2008-08-28 3 views

Répondre

13

Les personnes ici semblent confondre l'héritage protégé et les méthodes protégées. FWIW, je n'ai jamais vu quelqu'un 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++. Il y a peu de choses que vous ne pouvez pas faire si vous supprimez ce niveau de protection et ne comptez que sur le public et le privé.

+0

Juste un commentaire rapide: Monsieur C le nom de ++ est Stroustrup;) –

+0

Bon Dieu, je vais le corriger immédiatement.! :) –

1

C++ FAQ Lite mentionne un cas où l'utilisation de l'héritage privé est une solution légitime (Voir [24.3.] Which should I prefer: composition or private inheritance?). Il est quand vous voulez appeler la classe dérivée à partir d'une classe de base privée par le biais d'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 voulez tirer de la classe dérivée, et que vous souhaitez utiliser Base::service() depuis la classe dérivée (disons que vous voulez déplacer Derived::someFunction() vers la classe dérivée), la manière la plus simple d'y parvenir est de changer l'héritage privé de Base en héritage protégé.

Désolé, je ne peux pas penser à un exemple plus concret. Personnellement, j'aime rendre public tout l'héritage afin d'éviter de perdre du temps avec les discussions «Devrais-je faire en sorte que les relations d'héritage soient protégées ou privées?

+1

mais ce n'est pas ce que l'affiche a demandé, à propos de l'héritage protégé. Il y a certainement des cas où vous voudriez l'héritage privé, mais pas trop. –

5

Il existe un cas d'utilisation très rare de l'héritage protégé. Il est là que vous voulez 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 a essayé de cacher 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, il échouera dans la structure d2, car d2 ne sait pas que d1 est dérivé de base. Ainsi, covariance ne fonctionnera pas. Un moyen de s'en sortir est de les protéger, de sorte que l'héritage soit visible dans d2.

Un exemple similaire de l'utilisation de cette option est lorsque vous dérivez de std::ostream, mais que vous ne voulez pas que des personnes aléatoires écrivent dans votre flux. Vous pouvez fournir une fonction getStream virtuelle qui renvoie std::ostream&. Cette fonction pourrait faire un peu de préparation du flux pour la prochaine opération. Par exemple mettre certains manipulateurs dans

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

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