Quali sono gli specificatori di accesso? Dovrei ereditare con privati, protetti o pubblici?

Sono confuso riguardo al significato dei modificatori di accesso rispetto all’ereditarietà. Qual è la differenza tra ereditarietà che coinvolge le parole chiave private , protected e public ?

quali sono gli specificatori di accesso?

Ci sono 3 access specifiers per una class / struct / Union in C ++. Questi specificatori di accesso definiscono come accedere ai membri della class. Naturalmente, qualsiasi membro di una class è accessibile all’interno di quella class (all’interno di qualsiasi funzione membro della stessa class). Avanzando al tipo di specificatori di accesso, sono:

Pubblico – I membri dichiarati come pubblici sono accessibili dall’esterno della class attraverso un object della class.

Protetto : i membri dichiarati come protetti sono accessibili dall’esterno della class MA solo in una class derivata da esso.

Privato : questi membri sono accessibili solo all’interno della class. Non è consentito l’accesso esterno.

Un esempio di codice sorgente:

 class MyClass { public: int a; protected: int b; private: int c; }; int main() { MyClass obj; obj.a = 10; //Allowed obj.b = 20; //Not Allowed, gives compiler error obj.c = 30; //Not Allowed, gives compiler error } 

Specificatori di ereditarietà e accesso

L’ereditarietà in C ++ può essere uno dei seguenti tipi:

  • Eredità Private
  • Eredità Public
  • Eredità Protected

Ecco le regole di accesso dei membri per ognuno di questi:

Prima e più importante regola Private membri Private di una class non sono mai accessibili da nessuna parte eccetto i membri della stessa class.

Eredità pubblica:

Tutti Public membri Public della class base diventano membri Public della class derivata e
Tutti i membri Protected della class base diventano membri Protected della class derivata.

cioè nessun cambiamento nell’accesso dei membri. Le regole di accesso che abbiamo discusso prima sono ulteriormente applicate a questi membri.

Esempio di codice:

 Class Base { public: int a; protected: int b; private: int c; }; class Derived:public Base { void doSomething() { a = 10; //Allowed b = 20; //Allowed c = 30; //Not Allowed, Compiler Error } }; int main() { Derived obj; obj.a = 10; //Allowed obj.b = 20; //Not Allowed, Compiler Error obj.c = 30; //Not Allowed, Compiler Error } 

Eredità privata:

Tutti Public membri Public della class base diventano membri Private della class derivata e
Tutti i membri Protected della class base diventano membri Private della class derivata.

Un esempio di codice:

 Class Base { public: int a; protected: int b; private: int c; }; class Derived:private Base //Not mentioning private is OK because for classs it defaults to private { void doSomething() { a = 10; //Allowed b = 20; //Allowed c = 30; //Not Allowed, Compiler Error } }; class Derived2:public Derived { void doSomethingMore() { a = 10; //Not Allowed, Compiler Error, a is private member of Derived now b = 20; //Not Allowed, Compiler Error, b is private member of Derived now c = 30; //Not Allowed, Compiler Error } }; int main() { Derived obj; obj.a = 10; //Not Allowed, Compiler Error obj.b = 20; //Not Allowed, Compiler Error obj.c = 30; //Not Allowed, Compiler Error } 

Eredità protetta:

Tutti Public membri Public della class base diventano membri Protected della class derivata e
Tutti i membri Protected della class base diventano membri Protected della class derivata.

Un esempio di codice:

 Class Base { public: int a; protected: int b; private: int c; }; class Derived:protected Base { void doSomething() { a = 10; //Allowed b = 20; //Allowed c = 30; //Not Allowed, Compiler Error } }; class Derived2:public Derived { void doSomethingMore() { a = 10; //Allowed, a is protected member inside Derived & Derived2 is public derivation from Derived, a is now protected member of Derived2 b = 20; //Allowed, b is protected member inside Derived & Derived2 is public derivation from Derived, b is now protected member of Derived2 c = 30; //Not Allowed, Compiler Error } }; int main() { Derived obj; obj.a = 10; //Not Allowed, Compiler Error obj.b = 20; //Not Allowed, Compiler Error obj.c = 30; //Not Allowed, Compiler Error } 

Ricordare che le stesse regole di accesso si applicano alle classi e ai membri lungo la gerarchia dell’ereditarietà.


Punti importanti da notare:

– La specifica di accesso è per class non per object

Si noti che le specifiche di accesso C ++ funzionano in base alla class e non in base all’object.
Un buon esempio di ciò è che in un costruttore di copia o in una funzione di operatore Copia assegnazione è ansible accedere a tutti i membri dell’object passato.

– Una class derivata può accedere solo ai membri della propria class Base

Considera il seguente esempio di codice :

 class Myclass { protected: int x; }; class derived : public Myclass { public: void f( Myclass& obj ) { obj.x = 5; } }; int main() { return 0; } 

Fornisce un errore di compilazione:

prog.cpp: 4: errore: ‘int Myclass :: x’ è protetto

Poiché la class derivata può accedere solo ai membri della propria class base . Si noti che l’object object che viene passato qui non è in alcun modo correlato alla funzione di class derived a cui è stato acceduto, è un object completamente diverso e quindi la funzione membro derived non può accedere ai suoi membri.


Cos’è un friend ? In che modo l’ friend influisce sulle regole di specifica di accesso?

Puoi dichiarare una funzione o una class come friend di un’altra class. Quando lo fai, le regole di specifica di accesso non si applicano alla class / funzione friend ed. La class o la funzione possono accedere a tutti i membri di quella particolare class.

Quindi la rottura friend è incapsulata?

No, non lo fanno, al contrario migliorano l’incapsulamento!

friend nave friend è usata per indicare un forte accoppiamento intenzionale tra due entity framework.
Se esiste una relazione speciale tra due quadro in modo tale che è necessario accedere ad altri membri private o protected , ma non si vuole che tutti abbiano accesso usando l’identificatore di accesso public allora si dovrebbe usare la nave friend .

La spiegazione di Scott Meyers in Effective C ++ potrebbe aiutare a capire quando usarli – l’ereditarietà del pubblico dovrebbe essere un modello – una relazione, mentre l’ereditarietà privata dovrebbe essere usata per “è-implementata-in-termini-di” – quindi non hai per aderire all’interfaccia della superclass, stai solo riutilizzando l’implementazione.