Accès aux classes de base et dérivées

De Appmethod Topics
Aller à : navigation, rechercher

Remonter à Portée des membres - Index

Lorsque vous déclarez une classe dérivée D, vous énumérez les classes de base B1, B2, ... dans une liste-bases dont le délimiteur est une virgule :



 clé-classe D : liste-bases { <liste-membres> }



D hérite de tous les membres de ces classes de base. Les membres des classes de base redéfinies sont obtenus par héritage et sont accessibles via une redéfinition de portée. D ne peut utiliser que des membres public ou protected de ses classes de base. Mais quels vont être les attributs d'accès des membres dérivés tels que les voit D ? D souhaitera, par exemple, utiliser un membre public d'une classe de base, mais le rendre private dans la mesure où des fonctions extérieures sont impliquées. La solution consiste à appliquer des spécificateurs d'accès dans la liste-bases.

Remarque :   Puisqu'une classe de base peut être elle-même une classe dérivée, la question de l'attribut d'accès est récursive : vous revenez en arrière jusqu'à ce que vous parveniez à la première des classes de base, celle qui n'a hérité d'aucune autre.

Lorsque vous déclarez D, vous pouvez utiliser le spécificateur d'accès public, protected ou private devant chaque classe de la liste-bases :



 class D : public B1, private B2, ... {
   .
   .
   .
 }



Ces modificateurs ne changent pas les attributs d'accès des membres de base tels qu'ils sont perçus par la classe de base, même s'ils peuvent modifier ceux des membres de base tels que les voit la classe dérivée.

La valeur par défaut est private si D est une déclaration class, et public si D est une déclaration struct.

Remarque :   Les unions ne peuvent contenir aucune classe de base ni être utilisées comme classes de base.

La classe dérivée hérite des attributs d'accès d'une classe de base selon les principes suivants :

  • Classe de base public : les membres à accès public de la classe de base sont des membres public de la classe dérivée. Les membres à accès protected de la classe de base sont des membres protected de la classe dérivée. Les membres à accès private de la classe de base restent private pour la classe de base.
  • Classe de base protected : les membres à accès public et protected de la classe de base sont des membres protected de la classe dérivée. Les membres à accès private de la classe de base restent private pour cette classe.
  • Classe de base private : les membres à accès public et protected de la classe de base sont des membres private de la classe dérivée. Les membres à accès private de la classe de base restent private pour cette classe.

Vous remarquerez que les membres private d'une classe de base sont, et restent, inaccessibles aux fonctions membres de la classe dérivée, à moins que vous ne déclariez explicitement un spécificateur friend dans la classe de base pour autoriser l'accès. Par exemple,



 /* la classe X est dérivée de la classe A */
 class X : A {               // la valeur par défaut pour classe est private A
   .
   .
   .
 }
 /* la classe Y est dérivée (héritage multiple) de B et de C
    B devient par défaut private B */
 class Y : B, public C {     // remplacement de la valeur par défaut pour C
   .
   .
   .
 }
 /* struct S est dérivée de D */
 struct S : D {              // la valeur implicite pour struct est public D
   .
   .
   .
 }
 /* struct T est dérivée (héritage multiple) de D et E
    E devient par défaut public E */
 struct T : private D, E {   // remplacement de la valeur implicite pour D
                             // E est public par défaut
   .
   .
   .
 }



Les effets dus aux spécificateurs d'accès dans la liste de base sont adaptables à l'aide d'un nom-qualifié dans les déclarations public ou protected de la classe dérivée. Par exemple :



 class B {
    int a;               // private par défaut
 public:
    int b, c;
    int Bfunc(void);
 };
 class X : private B {   // a, b, c, Bfunc sont désormais private dans X
    int a;               // private par défaut, NOTE : a ne l'est pas
                         // accessible dans X
 public:
    B::c;                // c était private, il est devenu public
    int e;
    int Xfunc(void);
 };
 int Efunc(X& x);    // externe à B et X



La fonction Efunc() ne peut utiliser que les noms publics c, e et Xfunc().

La fonction Xfunc() de X, et dérivée de private B, a accès :

  • à c "devenu public"
  • aux membres "private-pour-X" à partir de B : b et Bfunc()
  • aux membres private et public de X : d, e et Xfunc()

Cependant, Xfunc() ne peut pas accéder au membre "private-pour-B", a.

Voir aussi