1133 votes

Différence entre héritage privé, public et protégé

J'ai cherché dans SO et je n'ai pas trouvé de bonne description concernant la différence entre public , private et protected L'héritage en C++. Toutes les questions supposaient un cas spécifique. Quelle est la différence ?

1606voto

Kirill V. Lyadvinsky Points 47627
class A 
{
public:
    int x;
protected:
    int y;
private:
    int z;
};

class B : public A
{
    // x is public
    // y is protected
    // z is not accessible from B
};

class C : protected A
{
    // x is protected
    // y is protected
    // z is not accessible from C
};

class D : private A
{
    // x is private
    // y is private
    // z is not accessible from D
};

NOTE IMPORTANTE : Les classes B, C et D contiennent toutes les variables x, y et z. C'est juste une question d'accès.

Sur l'utilisation de l'héritage protégé et privé, vous pouvez lire ici .

1151voto

Anzurio Points 4816

Pour répondre à cette question, j'aimerais d'abord décrire les accesseurs des membres avec mes propres mots. Si vous le savez déjà, passez directement à la rubrique "suivant :".

Il existe trois accesseurs à ma connaissance : public , protected et private .

Laissez :

class Base {
    public:
        int publicMember;
    private:
        int privateMember;
    protected:
        int protectedMember;
};
  • Tout ce qui est conscient de Base est également conscient que Base contient publicMember .
  • Seuls les enfants (et leurs enfants) sont conscients que Base contient protectedMember .
  • Personne d'autre que Base est conscient de privateMember .

Par "est conscient de", j'entends "reconnaît l'existence de, et donc est capable d'accéder à".

suivant :

Il en va de même pour l'héritage public, privé et protégé. Considérons une classe Base et une classe Child qui hérite de Base .

  • Si l'héritage est public tout ce qui est conscient de Base et Child est également conscient que Child hérite de Base.
  • Si l'héritage est protected seulement Child et ses enfants, sont conscients qu'ils héritent de Base .
  • Si l'héritage est private , personne d'autre que Child est conscient de l'héritage.

122voto

En limitant la visibilité de l'héritage, le code ne pourra pas voir qu'une classe hérite d'une autre classe : Les conversions implicites de la dérivée vers la base ne fonctionneront pas, et static_cast de la base à la dérivée ne fonctionnera pas non plus.

Seuls les membres/amis d'une classe peuvent voir l'héritage privé, et seuls les membres/amis et les classes dérivées peuvent voir l'héritage protégé.

public héritage

  1. L'héritage IS-A. Un bouton est une fenêtre, et partout où une fenêtre est nécessaire, un bouton peut être passé aussi.

    class button : public window { };

protégé héritage

  1. Protégé mis en œuvre en termes de. Rarement utile. Utilisé en boost::compressed_pair pour dériver à partir de classes vides et économiser de la mémoire en utilisant l'optimisation des classes de base vides (l'exemple ci-dessous n'utilise pas de template pour rester dans le sujet) :

    struct empty_pair_impl : protected empty_class_1 
    { non_empty_class_2 second; };
    
    struct pair : private empty_pair_impl {
      non_empty_class_2 &second() {
        return this->second;
      }
    
      empty_class_1 &first() {
        return *this; // notice we return *this!
      }
    };

privé héritage

  1. Mis en œuvre en termes de. L'utilisation de la classe de base sert uniquement à mettre en œuvre la classe dérivée. Utile avec les traits et si la taille importe (les traits vides qui ne contiennent que des fonctions utiliseront l'optimisation de la classe de base vide). Souvent confinement est la meilleure solution, cependant. La taille des chaînes de caractères est critique, c'est pourquoi on l'utilise souvent ici.

    template<typename StorageModel>
    struct string : private StorageModel {
    public:
      void realloc() {
        // uses inherited function
        StorageModel::realloc();
      }
    };

public membre

  1. Agrégat

    class pair {
    public:
      First first;
      Second second;
    };
  2. Accesseurs

    class window {
    public:
        int getWidth() const;
    };

protégé membre

  1. Fournir un accès amélioré pour les classes dérivées

    class stack {
    protected:
      vector<element> c;
    };
    
    class window {
    protected:
      void registerClass(window_descriptor w);
    };

privé membre

  1. Conserver les détails de la mise en œuvre

    class window {
    private:
      int width;
    };

Notez que les castings de style C permettent délibérément de faire un casting d'une classe dérivée vers une classe de base protégée ou privée d'une manière définie et sûre et de faire un casting dans l'autre sens également. Cela devrait être évité à tout prix, car cela peut rendre le code dépendant des détails d'implémentation - mais si nécessaire, vous pouvez utiliser cette technique.

69voto

Doug T. Points 33360

Il s'agit de la façon dont les membres publics de la classe de base sont exposés dans la classe dérivée.

  • public -> les membres publics de la classe de base seront publics (généralement par défaut).
  • protected -> les membres publics de la classe de base seront protégés.
  • private -> les membres publics de la classe de base seront privés.

Comme le souligne litb, l'héritage public est l'héritage traditionnel que l'on retrouve dans la plupart des langages de programmation. C'est-à-dire qu'il modélise une relation "IS-A". L'héritage privé, quelque chose d'AFAIK particulier au C++, est une relation "MISE EN ŒUVRE EN TERMES DE". C'est-à-dire que vous voulez utiliser l'interface publique dans la classe dérivée, mais ne veulent pas que l'utilisateur de la classe dérivée ait accès à cette interface. Beaucoup soutiennent que dans ce cas, il faut agréger la classe de base, c'est-à-dire qu'au lieu d'avoir la classe de base comme base privée, il faut en faire un membre de la classe dérivée afin de réutiliser la fonctionnalité de la classe de base.

37voto

kinshuk4 Points 586
Member in base class : Private   Protected   Public   

Type d'héritage :              Objet hérité en tant que :

Private            :   Private   Private     Private   
Protected          :   Private   Protected   Protected  
Public             :   Private   Protected   Public

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