2010-01-28 20 views
11

Sono davvero confuso sull'ereditarietà privata e sull'eredità protetta.L'ereditarietà protetta consente alla classe derivata di accedere ai membri privati ​​della sua classe base?

1) nell'ereditarietà protetta, i membri pubblici e protetti diventano membri protetti nella classe derivata. Nell'eredità privata, tutto è privato. Tuttavia, la classe derivata non può mai accedere ai membri privati ​​della classe base, giusto? La classe derivata può accedere ai membri pubblici e protetti in entrambi i casi. È giusto?

2) Ho notato che i membri privati ​​della classe base non verranno mai toccati dalla classe derivata. Allora perché i membri privati ​​sono ereditati?

risposta

32

Sei corretto al punto 1. Specificare private, protected o public quando l'ereditarietà da una classe di base non modifica nulla in senso di accessibilità sulla classe derivata stessa. Questi specificatori di accesso dicono al compilatore come trattare i membri della classe base quando le istanze della classe derivata sono usate altrove o se la classe derivata sembra essere usata come classe base per altre classi.

UPDATE: Possono aiutare ad illustrare le differenze:

class Base 
{ 
    private: int base_pri; 
    protected: int base_pro; 
    public: int base_pub; 
}; 

Per classi derivate dalla base:

class With_Private_Base : private Base { void memberFn(); }; 
class With_Protected_Base : protected Base { void memberFn(); }; 
class With_Public_Base : public Base { void memberFn(); }; 

// this would be the same for all of the above 3 classes: 
void With_PXXX_Base::memberFn() 
{ 
    base_pri = 1; // error: `int Base::base_pri' is private 
    base_pro = 1; // OK 
    base_pub = 1; // OK 
} 

Per classi derivate dalle 3 classi derivate:

class A : public With_Private_Base { void memberFn(); } 
void A::memberFn() 
{ 
    base_pri = 1; // error: `int Base::base_pri' is private 
    base_pro = 1; // error: `int Base::base_pro' is protected 
    base_pub = 1; // error: `int Base::base_pub' is inaccessible 
} 

class B : public With_Protected_Base { void memberFn(); } 
void B::memberFn() 
{ 
    base_pri = 1; // error: `int Base::base_pri' is private 
    base_pro = 1; // OK 
    base_pub = 1; // OK 
} 

class C : public With_Public_Base { void memberFn(); } 
void C::memberFn() 
{ 
    base_pri = 1; // error: `int Base::base_pri' is private 
    base_pro = 1; // OK 
    base_pub = 1; // OK 
} 

Accesso esterno alle prime tre classi derivate:

void main() 
{ 
    With_Private_Base pri_base; 
    pri_base.base_pri = 1; // error: `int Base::base_pri' is private 
    pri_base.base_pro = 1; // error: `int Base::base_pro' is protected 
    pri_base.base_pub = 1; // error: `int Base::base_pub' is inaccessible 

    With_Protected_Base pro_base; 
    pro_base.base_pri = 1; // error: `int Base::base_pri' is private 
    pro_base.base_pro = 1; // error: `int Base::base_pro' is protected 
    pro_base.base_pub = 1; // error: `int Base::base_pub' is inaccessible 

    With_Public_Base pub_base; 
    pub_base.base_pri = 1; // error: `int Base::base_pri' is private 
    pub_base.base_pro = 1; // error: `int Base::base_pro' is protected 
    pub_base.base_pub = 1; // OK 
} 
+0

l'ereditarietà e l'eredità pubblica sono uguali? –

+0

@fahad: dal punto di vista della classe derivata, sì, lo sono. Da un punto di vista di accesso esterno (l'ultimo blocco di codice nella mia risposta) sono piuttosto diversi. –

0

1) Sei corretto. Nessun tipo di ereditarietà consente l'accesso ai membri privati ​​(solo le dichiarazioni lo consentono)

2) Sono "ereditati" nel senso che un oggetto di tipo Derivato, se memorizzato, include tutti i dati membri di Derivato e Base, inclusi i membri privati ​​di Base. I membri privati ​​non possono semplicemente andarsene da quando i metodi di Base girano su quell'oggetto, avranno bisogno di accedere ai membri privati ​​di Base.

Inoltre, i nomi dei membri privati ​​di Base sono tecnicamente inclusi nei metodi di Derived, ma ovviamente si otterrà un errore di compilazione se si tenta di accedervi.

3

1a) L'ereditarietà protetta significa che il "figlio" può accedere a tutto ciò che può nell'ereditarietà pubblica, ma altri che utilizzano quell'oggetto possono vedere solo l'interfaccia pubblica al figlio, qualsiasi cosa nel suo genitore è nascosta.

1b) L'ereditarietà privata eredita tutte le funzioni pubbliche di una classe come funzioni private, vale a dire che non possono essere richiamate dal bambino o accessibili da un client dell'oggetto.

2) I membri privati ​​vengono ereditati perché potrebbero essere necessari dei metodi nella classe base su cui operare.

1

1) in eredità protetta, il membri pubblici e protetti diventano membri protetti nel derivato di classe. Nell'eredità privata, tutto è privato. Tuttavia, la classe derivata non può mai accedere ai membri privati ​​ della classe base, è corretto ?

Sì.

La classe derivata può l'accesso del pubblico e protetto membri in entrambi i casi. È giusto?

Sì.

2) Ho notato che i membri privati ​​ della classe di base non sarà mai toccati dalla classe derivata. Allora perché sono i membri privati ​​ereditati?

Perché fanno parte della classe base e serve la classe base che fa parte della classe derivata.Nota, puoi ancora manipolare alcuni stati (se ce ne sono) mantenuti nella classe base usando le funzioni membro non sovrascritte public/protected.

2
  1. Sì, questo è corretto. Le classi derivate possono accedere a membri pubblici protetti e protetti della sua classe base e la classe derivata non può accedere ai membri privati ​​della sua classe base.

  2. I membri privati ​​vengono ereditati per il seguente motivo: La classe base può definire una funzione pubblica protetta che modifica il membro privato della classe base. La classe derivata può chiamare questa funzione e pertanto deve conoscere la variabile privata a cui accede.

Problemi correlati