Question

Quelle est la différence entre public, private et héritage en C protected ++? Toutes les questions que j'ai trouvé sur SO traiter des cas spécifiques.

Était-ce utile?

La solution

Pour répondre à cette question, je voudrais décrire les accesseurs de membres d'abord dans mes propres mots. Si vous connaissez déjà, passez à la rubrique « suivante: ».

Il y a trois accesseurs que je connais: public, et protected private.

Soit:

class Base {
    public:
        int publicMember;
    protected:
        int protectedMember;
    private:
        int privateMember;
};
  • Tout ce qui est au courant de est également conscient Base que contient publicMember protectedMember.
  • Seuls les enfants (et leurs enfants) sont conscients que contient privateMember Child.
  • Personne ne mais est au courant de <=> <=>.

Par « est au courant », je veux dire « reconnaître l'existence et ainsi pouvoir accéder ».

suivant:

La même chose se produit avec l'héritage public, privé et protégé. Considérons une classe et une classe <=> <=> qui hérite de <=>.

  • Si l'héritage est <=>, tout ce qui est au courant de et <=> est également conscient <=> que hérite de <=> <=>.
  • Si l'héritage est <=>, que <=>, et ses enfants, sont conscients qu'ils héritent de <=>.
  • Si l'héritage est <=>, nul autre que est conscient de <=> l'héritage.

Autres conseils

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    // 'private' is default for classes
{
    // x is private
    // y is private
    // z is not accessible from D
};

IMPORTANT NOTE: Les classes B, C et D contiennent toutes les variables x, y et z. Il est juste question de l'accès.

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

Limiter la visibilité de l'héritage fera le code ne peut voir que certaines classe hérite une autre classe: les conversions implicites de la dérivée à la base ne fonctionnera pas, et de la base static_cast à 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é.

publique héritage

  1. IS-A héritage. 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 tirer de boost::compressed_pair des classes vides et économiser de la mémoire en utilisant l'optimisation de la classe de base vide (exemple ci-dessous ne pas utiliser modèle pour garder être au point):

    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ée héritage

  1. Mis en œuvre en termes de. L'utilisation de la classe de base est que pour la mise en œuvre de la classe dérivée. Utiles avec des traits et si les questions de taille (traits vides qui ne contiennent que des fonctions fera usage de l'optimisation de la classe de base vide). Souvent confinement est la meilleure solution, cependant. La taille des chaînes est critique, il est donc un usage souvent vu ici

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

publique membre

  1. Aggregate

    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ée membre

  1. Gardez les détails de mise en œuvre

    class window {
    private:
      int width;
    };
    

Notez que le style C moulages volontairement permet de mouler une classe dérivée d'une classe de base protégée ou privée dans un sens et de manière sûre et de jeter dans l'autre sens aussi. Cela devrait être évité à tout prix, car il peut faire un code dépendant des détails de mise en œuvre - mais si nécessaire, vous pouvez utiliser cette technique.

Il a à voir avec la façon dont les membres du public de la classe de base sont exposés à partir de la classe dérivée.

       
  • publique - les membres du public de classe de base> seront publiques (généralement la valeur par défaut)    
  • protégé -> les membres du public de la classe de base sera protégée    
  • privé - membres publics> classe de base sera privée

Comme litb souligne, l'héritage public est l'héritage traditionnel que vous verrez dans la plupart des langages de programmation. C'est modélise une relation « IS-A ». héritage privé, quelque chose propre à AFAIK C ++, est un « MIS EN OEUVRE EN TERMES DE » relation. C'est 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 d'avoir accès à cette interface. Beaucoup affirment que dans ce cas, vous devez regrouper la classe de base, qui est au lieu d'avoir la classe de base comme une base privée, faire dans un membre dérivé afin de réutiliser la fonctionnalité de classe de base.

Ces trois mots-clés sont également utilisés dans un contexte complètement différent pour spécifier le modèle d'héritage visibilité .

Ce tableau rassemble toutes les combinaisons possibles du modèle de déclaration des composants et l'héritage présentant l'accès aux composants résultant lorsque la sous-classe est complètement définie.

entrer image description ici

Le tableau ci-dessus est interprété de la manière suivante (jeter un regard sur la première rangée):

  

si un composant est déclarée publique et sa classe est hérité publique résultant accès publique .

Un exemple:

 class Super {
    public:      int p;
    private:     int q;
    protected:   int r;
 };

 class Sub : private Super {};

 class Subsub : public Sub {};

L'accès résultant pour les variables p, q, en classe r sous-sous pas .

  

Un autre exemple:

class Super {
    private:     int x;
    protected:   int y;
    public:      int z;
 };
class Sub : protected Super {};

L'accès résultant des variables y, z dans la classe Sub est protégé et pour x variable est aucun .

  

Un exemple plus détaillé:

class Super {
private:
    int storage;
public:
    void put(int val) { storage = val;  }
    int  get(void)    { return storage; }
};
int main(void) {
    Super object;

    object.put(100);
    object.put(object.get());
    cout << object.get() << endl;
    return 0;
}

permet maintenant de définir une sous-classe:

class Sub : Super { };

int main(void) {
    Sub object;

    object.put(100);
    object.put(object.get());
    cout << object.get() << endl;
    return 0;
}

La classe définie sous le nom qui est une sous-classe de la classe appelée Super ou qui Sub classe est dérivée de la classe put. La classe introduit ni nouvelles get variables ni nouvelles fonctions. Est-ce que cela veut dire que tout objet de la classe hérite de tous les error: 'int Super::storage' is protected traits après la classe étant en fait <=> une copie d'un des objets de classe <=>?

Non . Il ne fonctionne pas.

Si nous compilons le code suivant, nous n'obtiendrons rien mais des erreurs de compilation et disant que <=> méthodes sont inaccessibles <=>. Pourquoi?

Lorsque nous omettons le spécificateur de visibilité, le compilateur suppose que nous allons appliquer la soi-disant héritage privé . Cela signifie que tous les publics composants superclasse se transforment en privée accès, composants superclasse privés ne seront pas accessibles à tous. Cela signifie par conséquent que vous n'êtes pas autorisé à utiliser ce dernier dans la sous-classe.

Nous devons informer le compilateur que nous voulons préserver la politique d'accès utilisé précédemment.

class Sub : public Super { };
  

Ne soyez pas induits en erreur : cela ne signifie pas que les composants privés du Super   classe (comme la variable de stockage) va se transformer en les publics dans un   manière un peu magique. privée composants restent privée , publique   restera publique .

Les objets de la classe peut faire <=> « presque » les mêmes choses que leurs frères et sœurs plus âgés créés à partir de la classe <=>. « Presque » parce que le fait d'être une sous-classe signifie également que le classe a perdu l'accès aux composants privés de la superclasse . Nous ne pouvons pas écrire une fonction de membre de la classe qui <=> pouvoir manipuler directement la variable de stockage.

Ceci est une restriction très grave. Y at-il solution?

Oui .

Le troisième niveau d'accès est appelé protégé . Le mot-clé protégée signifie que le composant marqué avec elle se comporte comme un public lorsque utilisé par l'une des sous-classes et ressemble à un privé pour le reste du monde . - Ceci est vrai que pour les classes publiques héritées (comme la classe super dans notre exemple) -

class Super {
protected:
    int storage;
public:
    void put(int val) { storage = val;  }
    int  get(void)    { return storage; }
};

class Sub : public Super {
public:
    void print(void) {cout << "storage = " << storage;}
};

int main(void) {
    Sub object;

    object.put(100);
    object.put(object.get() + 1);
    object.print();
    return 0;
}

Comme vous le voyez dans le code exemple nous une nouvelle fonctionnalité à la classe et il <=> fait une chose importante: il accède à la variable de stockage de la classe super .

Il ne serait pas possible si la variable a été déclarée comme privée. Dans la portée principale fonction la variable reste cachée de toute façon, donc si vous écrivez quelque chose comme:

object.storage = 0;

Le compilateur vous informe qu'il est un <=>.

Enfin, la lprogramme ast produira la sortie suivante:

storage = 101
Member in base class : Private   Protected   Public   

Type d'héritage : Objet hérité comme :

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

1) L'héritage public :

a. Les membres privés de la classe de base ne sont pas accessibles en classe dérivée.

b. membres protégés de la classe de base restent protégés en classe dérivée.

c. Les membres du public de la classe de base restent publiques en classe dérivée.

Alors, d'autres classes peuvent utiliser les membres du public de la classe de base par objet de classe dérivée.

2) Protégé Inheritance :

a. Les membres privés de la classe de base ne sont pas accessibles en classe dérivée.

b. membres protégés de la classe de base restent protégés en classe dérivée.

c. Les membres du public de la classe de base deviennent aussi membres protégés de classe dérivée.

Alors, d'autres classes ne peuvent pas utiliser les membres du public de la classe de base par objet de classe dérivée; mais ils sont à la disposition de la sous-classe des dérivés.

3) Héritage privé :

a. Les membres privés de la classe de base ne sont pas accessibles en classe dérivée.

b. membres protégés et publics de la classe de base deviennent membres privés de classe dérivée.

Ainsi, aucun membre de la classe de base sont accessibles par d'autres classes par objet de classe dérivée car ils sont privés de classe dérivée. Ainsi, même sous-classe de Derived classe ne peut pas y accéder.

modèles d'héritage public une IS-une relation. Avec

class B {};
class D : public B {};

tous les D est un B.

Modèles d'héritage privé une relation IS-MIS EN OEUVRE-UTILISATION (ou ce qui est appelé). Avec

class B {};
class D : private B {};

est b_ pas un protected, mais chaque utilise son <=> dans sa mise en œuvre <=>. l'héritage privé peut toujours être éliminé en utilisant à la place de confinement:

class B {};
class D {
  private: 
    B b_;
};

Cette <=>, aussi, peut être mis en œuvre à l'aide <=>, dans ce cas, en utilisant son <=>. Le confinement est un couplage moins étroit entre les types que l'héritage, donc en général, il devrait être préféré. Parfois, en utilisant le confinement au lieu de l'héritage privé est pas aussi pratique que l'héritage privé. Souvent, c'est une piètre excuse pour être paresseux.

Je ne pense pas que quelqu'un sait ce que les modèles d'héritage <=>. Au moins, je ne l'ai pas encore vu aucune explication convaincante.

Si vous héritez publiquement d'une autre classe, tout le monde sait que vous héritez et vous pouvez être utilisé par quiconque polymorphically par un pointeur de classe de base.

Si vous héritez protectedly seulement vos enfants des classes seront en mesure de vous utiliser polymorphically.

Si vous héritez ne vous sera privé en mesure d'exécuter des méthodes de classe parent.

Ce qui symbolise essentiellement la connaissance du reste des classes ont au sujet de votre relation avec votre classe parente

Les membres de données protégées sont accessibles par toutes les classes qui héritent de votre classe. les membres de données privées, peuvent cependant pas. Disons que nous avons ce qui suit:

class MyClass {
    private:
        int myPrivateMember;    // lol
    protected:
        int myProtectedMember;
};

À partir de votre extension à cette classe, le référencement ne fonctionnera pas this.myPrivateMember. Cependant, la volonté this.myProtectedMember. La valeur est toujours encapsulée, donc si nous avons une instanciation de cette classe appelée myObj, alors ne fonctionnera pas myObj.myProtectedMember, il est donc fonction similaire à un membre de données privées.

Accessors    | Base Class | Derived Class | World
—————————————+————————————+———————————————+———————
public       |      y     |       y       |   y
—————————————+————————————+———————————————+———————
protected    |      y     |       y       |   n
—————————————+————————————+———————————————+———————
private      |            |               |    
  or         |      y     |       n       |   n
no accessor  |            |               |

y: accessible
n: not accessible

Basé sur ce exemple java ... Je pense qu'une petite table vaut mille mots:)

Résumé:

  • privé: personne ne peut le voir à l'exception dans la classe
  • Protégées: + Private classes dérivées peuvent voir
  • Public: le monde peut le voir

Lors de l'héritage, vous pouvez (dans certaines langues) changer le type de protection d'un membre de données dans certains sens, par exemple de la protection au public.

Privé:

Les membres privés d'une classe de base ne sont accessibles par les membres de cette classe de base.

Public:

Les membres du public d'une classe de base peuvent être consultés par les membres de cette classe de base, des membres de la classe dérivée, ainsi que les éléments qui sont en dehors de la classe de base et la classe dérivée.

Protégé:

Les membres protégés d'une classe de base sont accessibles par les membres de la classe de base ainsi que des membres de sa classe dérivée.


En bref:

private : Base

protégé : base + dérivée

publique : base + + dérivée de tout autre membre

J'ai trouvé une réponse facile et donc pensé à l'affichage pour ma référence future aussi.

Son des liens http: //www.learncpp .com / cpp-tutorial / 115-patrimoine-et-access-spécificateurs /

class Base
{
public:
    int m_nPublic; // can be accessed by anybody
private:
    int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
protected:
    int m_nProtected; // can be accessed by Base member functions, or derived classes.
};

class Derived: public Base
{
public:
    Derived()
    {
        // Derived's access to Base members is not influenced by the type of inheritance used,
        // so the following is always true:

        m_nPublic = 1; // allowed: can access public base members from derived class
        m_nPrivate = 2; // not allowed: can not access private base members from derived class
        m_nProtected = 3; // allowed: can access protected base members from derived class
    }
};

int main()
{
    Base cBase;
    cBase.m_nPublic = 1; // allowed: can access public members from outside class
    cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
    cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
}

Il est essentiellement la protection d'accès des membres publics et protégés de la classe de base dans la classe dérivée. Héritage public, la classe dérivée peut voir les membres du public et protégés de la base. Avec l'héritage privé, il ne peut pas. Avec la protection, la classe dérivée et toutes les classes dérivées de qui peut les voir.

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