Cerca nel sito:
ricerca
avanzata

Frasi Celebri...

Colui al quale confidate il vostro segreto, diventa padrone della vostra libert

Fran?ois De La Rochefoucauld 

Sondaggio:

Come va la vita con l'Euro?

Ottimo!
Come prima
Fatico ma imparer?
Porc... che macello!

visualizza risultati


 

Ereditarieta` pubblica, privata e protetta

 

Per default l'ereditarieta` e` privata, tutti i membri ereditati diventano cioe` membri privati della classe derivata e non sono quindi parte della sua interfaccia. E` possibile alterare questo comportamento richiedendo un'ereditarieta` protetta o pubblica (e` anche possibile richiedere esplicitamente l'ereditarieta` privata), ma quello che bisogna sempre ricordare e` che non si puo` comunque allentare il grado di protezione di un membro ereditato (i membri privati rimangono dunque privati e comunque non accessibili alla classe derivata):

  • Con l'ereditarieta` pubblica i membri ereditati mantengono lo stesso grado di protezione che avevano nella classe da cui si eredita (classe base immediata): i membri public rimangono public e quelli protected continuano ad essere protected;
  • Con l'ereditarieta` protetta i membri public della classe base divengono membri protected della classe derivata; quelli protected rimangono tali.
La sintassi completa per l'ereditarieta` diviene dunque:
  class < DerivedClassName > : [< Qualifier >] < BaseClassName > {
    /* ... */
  };
dove Qualifier e` opzionale e puo` essere uno tra public, protected e private; se omesso si assume private.
Lo standard ANSI consente anche la possibilita` di esportare singolarmente un membro in presenza di ereditarieta` privata o protetta, con l'ovvio limite di non rilasciare il grado di protezione che esso possedeva nella classe base:


  class MyClass {
    public:
      void PublicMember(int, char);
      void Member2();
      /* ... */

    protected:
      int ProtectedMember;
      /* ... */

    private:
      /* ... */
  };

  class Derived1 : private MyClass {
    public:
      MyClass::PublicMember;     // esporta una specifica
                                 // funzione membro
      using MyClass::Member2;    // si puo ricorrere
                                 // anche alla using

      MyClass::ProtectedMember;  // Errore!
      /* ... */
  };

  class Derived2 : private MyClass {
    public:
      MyClass::PublicMember;     // Ok!

    protected:
      MyClass::ProtectedMember;  // Ok!
      /* ... */
  };

  class Derived3 : private MyClass {
    public:
      /* ... */

    protected:
      MyClass::PublicMember;     // Ok era public!
      MyClass::ProtectedMember;  // Ok!
      /* ... */
  };


L'esempio mostra sostanzialmente tutte le possibili situazioni, compresa il caso di un errore dovuto al tentativo di far diventare public un membro che era protected.
Si noti la notazione utilizzata, non e` necessario specificare niente piu` del semplice nome del membro preceduto dal nome della classe base e dal risolutore di scope. Un metodo alternativo e` dato dall'uso della direttiva using per importare nel namespace della classe derivata, un nome appartenente al namespace della classe base.
La possibilita` di esportare singolarmente un membro e` stata introdotta per fornire un modo semplice per nascondere all'utente della classe derivata l'interfaccia della classe base, salvo alcune cose; si sarebbe potuto procedere utilizzando l'ereditarieta` pubblica e ridefinendo le funzioni che non si desiderava esportare in modo che non compiano azioni dannose, il metodo pero` presenta alcuni inconvenienti:

  1. Il tentativo di utilizzare una funzione non esportata viene segnalato solo a run-time;
  2. E` una operazione che costringe il programmatore a lavorare di piu` aumentando la possibilita` di errore e diminuendone la produttivita`.

D'altronde l'uso di funzioni di forward (cioe` funzioni "guscio" che servono a richiamarne altre), risolverebbe il primo punto, ma non il secondo.

I vari "tipi" di derivazione (ereditarieta`) hanno conseguenze che vanno al di la` della semplice variazione del livello di protezione di un membro.
Con l'ereditarieta` pubblica si modella effettivamente una relazione di tipo Is-a poiche` la classe derivata continua ad esportare l'interfaccia della classe base (e` cioe` possibile utilizzare un oggetto derived come un oggetto base); con l'ereditarieta` privata questa relazione cessa, in un certo senso possiamo vedere l'ereditarieta` privata come una sorta di contenimento. L'ereditarieta` protetta e` invece una sorta di ibrido ed e` scarsamente utilizzata.

 

successivo
–«  INDICE  »–

 

 

 

 

 
Powered by paper&pencil (carta&matita ) - Copyright © 2001-2022 Cataldo Sasso