Verschil tussen private, publieke en beschermde erfenis

Wat is het verschil tussen public, privateen protectedovererving in C++?

Alle vragen die ik op SO heb gevonden, gaan over specifieke gevallen.


Antwoord 1, autoriteit 100%

Om die vraag te beantwoorden, wil ik eerst de accessoires van leden in mijn eigen woorden beschrijven. Als je dit al weet, ga dan naar het kopje “volgende:”.

Er zijn drie accessors die ik ken: public, protecteden private.

Laat:

class Base {
    public:
        int publicMember;
    protected:
        int protectedMember;
    private:
        int privateMember;
};
  • Alles wat op de hoogte is van Baseweet ook dat BasepublicMemberbevat.
  • Alleen de kinderen (en hun kinderen) weten dat BaseprotectedMemberbevat.
  • Niemand behalve Basekent privateMember.

Met “is op de hoogte van”, bedoel ik “het bestaan erkennen van, en dus toegang hebben”.

volgende:

Hetzelfde gebeurt met publieke, private en beschermde erfenissen. Laten we eens kijken naar een klasse Baseen een klasse Childdie erft van Base.

  • Als de overerving publicis, weet alles wat bekend is met Baseen Childook dat Childerft van Base.
  • Als de erfenis protectedis, weten alleen Childen zijn kinderen dat ze erven van Base.
  • Als de erfenis privateis, is niemand anders dan Childop de hoogte van de erfenis.

2, Autoriteit 138%

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
};

Belangrijke opmerking: klassen B, C en D bevatten allemaal de variabelen x, y en z. Het is gewoon een kwestie van toegang.

Over het gebruik van beschermde en private erfenis die u hier kunt lezen.


3, Autoriteit 11%

Beperking van de zichtbaarheid van erfenis zal code maken, niet in staat om te zien dat sommige klasse erft een andere klasse: impliciete conversies van de afgeleide aan de basis zullen niet werken, en static_castvan de basis naar de afgeleide zal ook niet werken.

Alleen leden / vrienden van een klasse kunnen privé-erfenis zien, en alleen leden / vrienden en afgeleide klassen kunnen beschermde overerving zien.

openbaar erfenis

  1. is-een erfenis. Een knop is-een venster en overal waar een venster nodig is, kan ook een knop worden doorgegeven.

    class button : public window { };
    

beschermd erfenis

  1. Beschermd geïmplementeerd geïmplementeerd-in-termen. Zelden nuttig. Gebruikt in boost::compressed_pairOm af te leiden van lege klassen en het opslaan van geheugen met behulp van de lege basisklasse-optimalisatie (bijvoorbeeld hieronder gebruikt sjabloon om op het punt te blijven):

    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é erfenis

  1. Implementated-in-termen-van. Het gebruik van de basisklasse is alleen voor het implementeren van de afgeleide klasse. Handig met eigenschappen en indien grootte aangelegenheden (lege kenmerken die alleen functies bevatten, zullen gebruik maken van de lege optimalisatie van de basisklasse). Vaak is containment echter de betere oplossing. De grootte voor snaren is van cruciaal belang, dus het is hier een vaak gezien gebruik

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

openbaar lid

  1. Aggregate

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

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

beschermd lid

  1. Verschaffing van verbeterde toegang voor afgeleide klassen

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

privé lid

  1. Houd Implementatiedetails

    class window {
    private:
      int width;
    };
    

Merk op dat C-Style Casts opzettelijk een afgeleide klasse mogelijk maakt op een beveiligde of privé-basisklasse op een gedefinieerde en veilige manier en ook in de andere richting. Dit moet ten koste van alles worden vermeden, omdat het codeafhankelijk kan maken van implementatiedetails – maar indien nodig kunt u gebruik maken van deze techniek.


Antwoord 4, autoriteit 6%

Het heeft te maken met hoe de openbare leden van de basisklasse worden weergegeven vanuit de afgeleide klasse.

  • openbaar -> openbare leden van de basisklasse zijn openbaar (meestal de standaard)
  • beschermd -> openbare leden van de basisklasse worden beschermd
  • particuliere – & gt; De openbare leden van de basisklasse zullen privé zijn

Naarmate Litb verwijst, is het openbaar erfenis traditionele erfenis dat u in de meeste programmeertalen zult zien. Dat is het modelleren van een “IS-A” -relatie. Particuliere erfenis, iets afaik eigen aan C++, is een “geïmplementeerd in termen van” relatie. Dat wil je gebruiken de openbare interface in de afgeleide klasse, maar wil niet dat de gebruiker van de afgeleide klasse toegang heeft tot die interface. Velen beweren dat u in dit geval de basisklasse moet aggregeren, in plaats van de basisklasse als een privébasis, in een lid van afgeleid om de functionaliteit van de basisklasse opnieuw te gebruiken.


5, Autoriteit 3%

Member in base class : Private   Protected   Public   

overerving type : & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; object geërfd als :

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

6, Autoriteit 2%

1) Openbaar erfenis :

a. Particuliere leden van de basisklasse zijn niet toegankelijk in de afgeleide klasse.

b. Beschermde leden van de basisklasse blijven beschermd in afgeleide klasse.

c. Openbare leden van de basisklasse blijven openbaar in afgeleide klasse.

Dus kunnen andere klassen openbare leden van baseklasse gebruiken via afgeleide klassenobject.

2) Beschermde erfenis :

a. Particuliere leden van de basisklasse zijn niet toegankelijk in de afgeleide klasse.

b. Beschermde leden van de basisklasse blijven beschermd in afgeleide klasse.

c. Openbare leden van de basisklasse worden ook beschermde leden van afgeleide klasse.

Dus kunnen andere klassen geen openbare leden van baseklasse gebruiken via afgeleide klassenobject; Maar ze zijn beschikbaar voor het afgeleide afval.

3) Privé-erfdeel :

a. Particuliere leden van de basisklasse zijn niet toegankelijk in de afgeleide klasse.

b. Beschermd en versterker; Openbare leden van basisklasse worden particuliere leden van afgeleide klasse.

Dus, geen leden van de basisklasse zijn toegankelijk via andere klassen via afgeleide klassenobject, omdat ze privé in afgeleide klasse zijn. Dus, zelfs subklasse van afgeleid
klas heeft geen toegang tot ze.


Antwoord 7

Als je publiekelijk erft van een andere klasse, weet iedereen dat je erft en kun je door iedereen polymorf worden gebruikt via een pointer van de basisklasse.

Als je beschermd erft, kunnen alleen de klassen van je kinderen je polymorf gebruiken.

Als u privé erft, kan alleen uzelf de methodes van de bovenliggende klassen uitvoeren.

Wat in feite de kennis symboliseert die de rest van de klassen hebben over je relatie met je ouderklas


Antwoord 8

Beschermde gegevensleden zijn toegankelijk voor alle klassen die van uw klas overerven. Leden van privégegevens kunnen dat echter niet. Laten we zeggen dat we het volgende hebben:

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

Vanuit je extensie naar deze klasse, zal het verwijzen naar this.myPrivateMemberniet werken. this.myProtectedMemberechter wel. De waarde is nog steeds ingekapseld, dus als we een instantie van deze klasse hebben met de naam myObj, dan zal myObj.myProtectedMemberniet werken, dus het is vergelijkbaar in functie met een privé gegevenslid.


Antwoord 9

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

Gebaseerd op ditvoorbeeld voor java… Ik denk dat een kleine tabel meer zegt dan duizend woorden 🙂


Antwoord 10

Samenvatting:

  • Privé: niemand kan het zien, behalve binnen de klas
  • Beveiligd: privé + afgeleide klassen kunnen het zien
  • Openbaar: de wereld kan het zien

Bij het overnemen kunt u (in sommige talen) het beveiligingstype van een gegevenslid in een bepaalde richting wijzigen, bijv. van beveiligd naar openbaar.


Antwoord 11

Privé:

De privéleden van een basisklasse zijn alleen toegankelijk voor leden van die basisklasse.

Openbaar:

De openbare leden van een basisklasse zijn toegankelijk voor leden van die basisklasse, leden van de afgeleide klasse en de leden die buiten de basisklasse en afgeleide klasse vallen.

Beveiligd:

De beschermde leden van een basisklasse zijn toegankelijk voor zowel leden van de basisklasse als leden van de afgeleide klasse.


Kortom:

privé: basis

beschermd: basis + afgeleid

openbaar: basis + afgeleid + elk ander lid


Antwoord 12

Ik heb geprobeerd overerving uit te leggen aan de hand van een afbeelding hieronder.

De hoofdgist is dat de particuliere leden van de moederklasse nooit rechtstreeks toegankelijk zijn van afgeleide / kindklasse, maar u kunt de lidfunctie van de oudercategorie gebruiken om toegang te krijgen tot de particuliere leden van de moederklasse.
Private variabelen zijn altijd aanwezig in afgeleide klasse, maar het kan niet worden geopend door afgeleide klasse. Het is net zo, maar je kunt niet zien met je eigen ogen, maar als je vraagt ​​dat iemand de bovenliggende klasse vormt, dan kan hij het aan jou beschrijven.


13

Ik vond een eenvoudig antwoord en dus dacht ik het ook te plaatsen voor mijn toekomstige referentie.

Het is van de links http: // www. Learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/

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
}

Antwoord 14

Het is in wezen de toegangsbeveiliging van de openbare en beschermde leden van de basisklasse in de afgeleide klasse. Met openbare overerving kan de afgeleide klasse openbare en beschermde leden van de basis zien. Bij privé-erfenis kan dat niet. Met beschermd kunnen de afgeleide klasse en alle klassen die daarvan afgeleid zijn ze zien.

Other episodes