User Tools

Site Tools


cpp:syntax:class:deriving

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
cpp:syntax:class:deriving [2019/09/24 06:20]
127.0.0.1 external edit
cpp:syntax:class:deriving [2022/11/18 10:47] (current)
Line 1: Line 1:
-====== ​La classe ​dérivée ======+====== ​Classe ​dérivée ​& héritage ​======
  
-La classe dérivée est une **extension** ​d'une classe ​de base. C'est une classe à laquelle on a ajouté des __champs__ et des __fonctions membres__ supplémentaires.+===== Pourquoi hériter ​d'une classe ​====
  
-La classe dérivée **hérite** de l'​ensemble des __fonctions membres__ et des __champs__ définis par la ou les classes de bases. C'est pour cela que l'on parle d'​héritage quand on parle de classes dérivées d'une autre classe.+Supposons ​que nous avons réaliser un objet qui effectuer une certaine tâche ​de base
  
 +<code cpp>
 +class enumerate_characters
 +{
 +private:
 +  int mPosition;
 +  int mNumberOfCharacters;​
 +  const char* mString;
 +public:
 +  enumerate_characters(const char* aString, int theNumberOfCharacters):​
 +      mString(aString),​ mNumberOfCharacters(theNumberOfCharacters) {}
 +  ​
 +  int next()
 +  {
 +      return mPosition < mNumberOfCharacters ? 
 +        (int)mString[mPosition++] : -1;
 +  }
 +  void reset()
 +  {
 +      mPosition = 0;
 +  }
 +}
 +</​code>​
  
 +Cette classe énumère les caractère de la chaîne de caractère passée en paramètre en commençant par le premier caractère et en terminant par le dernier caractère.
  
-===== Déclaration d'une classe dérivée ​====+Supposant que je ne souhaite plus énumérer les caractères en commençant par le premier caractère et en terminant par le dernier caractère mais à l'inverse en commençant par le dernier caractère et en terminant par le premier. Je devrais ajouter à cette classe la fonction ''​previous()''​ par exemple. Je peux soit ajouter cette méthode dans la classe ou au contraire ajouter cette méthode à une extension de la classe, ce que l'on appelle ​une classe dérivée ​ou une classe fille qui hérite de son parent. L'​intérêt est dans ce cas que je vais pouvoir modifier le comportement de la classe.
  
-La syntaxe pour déclarer une classe comme héritant d'une classe de base est la suivante : 
 <code cpp> <code cpp>
- +class enumerate_characters
-class DerivingClass:​ public BaseClass+
 { {
-};+private: 
 +  int mPosition;​ 
 +protected:​ 
 +  int mNumberOfCharacters;​ 
 +  const char* mString; 
 +public: 
 +  enumerate_characters(const char* aString, int theNumberOfCharacters):​ 
 +      mString(aString),​ mNumberOfCharacters(theNumberOfCharacters) {} 
 +   
 +  int next() 
 +  { 
 +      return mPosition < mNumberOfCharacters ?  
 +        (int)mString[mPosition++] : -1; 
 +  } 
 +  void reset() 
 +  { 
 +      mPosition = 0; 
 +  } 
 +}
  
 +class bidi_enumerate_characters:​ enumerate_characters
 +{
 +private:
 +  int mReversePosition;​
 +public:
 +  bidi_enumerate_characters(const char* aString, int theNumberOfCharacters):​
 +      enumerate_characters(aString,​ theNumberOfCharacters),​ mReversePosition(theNumberOfCharacters) {}
 +  ​
 +  int previous()
 +  {
 +      return mReversePosition >= 0 ? 
 +        (int)mString[mPosition++] : -1;
 +  }
 +  void reset()
 +  {
 +      mReversePosition= mNumberOfCharacters;​
 +      enumerate_characters()::​reset();​
 +  }
 +}
 </​code>​ </​code>​
  
-==== Accessibilité des méthodes d'​une ​classe ​de base ====+La classe ​''​bidi_enumerate_characters''​ est une extension ​de la classe ''​enumerate_characters''​ :
  
-Cette définition indique que la classe ''​DerivingClass''​ hérite de la classe ''​BaseClass''​ et donc que l'​ensemble des méthodes et des champs définis par la classe ''​BaseClass''​ sont présents dans la classe ''​DerivingClass''​. Cependant, il faut faire attention, présent ne veut pas dire qu'ils sont accessibles dans la classe de base. Ainsi, nous avons les règles d'​accessibilité suivantes pour les méthodes et les champs définis dans la classe de base.+<code cpp> 
 +class bidi_enumerate_characters:​ enumerate_characters 
 +
 +</​code>​
  
-^ Déclaration ​dans la classe ​de base ^ Accesibilité ​dans la classe ​dérivée ^  +ce qui veut que l'​ensemble des champs et méthodes présents ​dans la classe ​''​enumerate_characters''​ sont présents ​dans la classe ''​bidi_enumerate_characters''​. Attention, ​les champs ​ou méthodes ​privées ​sont présentes mais ne sont pas accessibles. Ici, nous avons besoin des champs ''​mNumberOfCharacters''​ et ''​mString''​ dans la classe dérivée, c'est pour cela que nous avons modifié ​la classe de base ''​enumerate_characters''​ pour les rendre toujours inaccessibles en dehors de la classe ​mais accessible dans les classes derivées en les déclarant comme ''​proctected'' ​:
-|les champs ou méthodes déclarés ​''​public'' ​dans la classe de base | les champs ​et méthodes sont accessibles ​dans la classe dérivée | +
-|les champs ​ou méthodes déclarés ​''​protected''​ dans la classe de base les champs et méthodes sont accessibles dans la classe ​dérivée | +
-|les champs ou méthodes déclarés ​''​private'' ​dans la classe de base | les champs et méthodes ne sont pas accessibles dans la classe dérivée |+
  
-Cependant, il faut aussi s'​intéresser à l'​accesibilité des méthodes en dehors de la classe dérivée. C'est ici qu'​intervient les attributs d'​accessibilité que l'on place devant le type de la classe dont hérite qui peuvent être ''​public'',​ ''​protected''​ ou ''​private''​.+<code cpp> 
 +class enumerate_characters 
 +
 +private
 +  int mPosition;​ 
 +protected:​ 
 +  int mNumberOfCharacters;​ 
 +  const char* mString; 
 +public: 
 +</​code>​
  
-^ Attribut d'​héritage ^ Accessibilité en dehors de la classe ​^ Accessibilité dans une classe dérivant de ''​DerivingClass'' ​+Nous voyons que la classe ''​bidi_enumerate_characters'' ​ajoute ​la fonction ​''​previous()''​ à la classe de base.
-|''​DerivingClass:​ public BaseClass''​| Les méthodes et champs ''​public''​ de ''​BaseClass''​ sont accessibles. | Les méthodes et champs ''​public''​ ou ''​protected''​ de ''​BaseClass''​ sont accessibles à la classe dérivée. | +
-|''​DerivingClass:​ private BaseClass''​| Aucune méthode ou champs de ''​BaseClass''​ ne sont accessibles. | Aucune méthode ou champs de ''​BaseClass''​ ne sont accessibles ​à la classe ​dérivée. | +
-|''​DerivingClass:​ protected BaseClass''​| Aucune méthode ou champs ​de ''​BaseClass''​ sont accessibles. | Les méthodes et champs ''​public''​ ou ''​protected''​ de ''​BaseClass''​ sont accessibles à la classe dérivée|+
  
 +<code cpp>
 +  int previous()
 +  {
 +      return mReversePosition >= 0 ? 
 +        (int)mString[mPosition++] : -1;
 +  }
 +</​code>​
  
-===== L'héritage multiple ====+c'est pour cela qu'on dit qu'une classe dérivée est une extension de la classe de base par ce qu'​elle peut ajouter des fonctions et des comportements. ​
  
-Il est possible d'hériter de plus d'une classe. Pour ce faire, il suffit de spécifier ​la liste des classes dont nous souhaitons hériter comme suit:+Ensuite, nous constatons que la classe ​''​bidi_enumerate_characters''​ rédéfinit ​la méthode ''​reset()'' ​:
  
 <code cpp> <code cpp>
 +  void reset()
 +  {
 +      mReversePosition= mNumberOfCharacters;​
 +      enumerate_characters()::​reset();​
 +  }
 +</​code>​
  
-class DerivingClass:​  +En effetlorsque nous appellons la méthode ''​reset()''​nous mettons d'​abord le champs ''​mReversePosition''​ à ''​mNumberOfCharacters''​ et puis ensuite nous appellons la méthode ''​reset()''​ de la classe de base ''​enumerate_characters()::​reset()''​. Nous avons spécialisé le comportement de la fonction ''​reset()''​ par rapport à la fonction ''​reset()''​ de la classe de base. C'est pour cela que les classes dérivées sont aussi appellées classes spécialisées.
-    public BaseClass +
-    private ImplementationClass +
-    public AnotherBaseClass +
-+
-};+
  
-</​code>​+[[cpp:​syntax:​class:​deriving:​creating|Définir une classe dérivée]] 
 + 
 +[[cpp:​syntax:​class:​deriving:​methods|Définir champs et méthodes dans une classe dérivée]] 
 + 
 +[[cpp:​syntax:​class:​deriving:​constructor|Définir les constructeurs dans une classe dérivée]]
  
-Si l'​héritage multiple est intellectuellement intéressant,​ rapidement nous pouvons avoir des problèmes de conflit entres les différentes fonctions membres définies dans les différentes classes de base. De même, nous pouvons avoir aussi des problèmes d'​initialisation des différents champs des classes de base. C'est pour cela que vous trouverez l'​ensemble des aspects relatifs à l'​héritage multiple dans cette [[in204:cpp:​syntax:​class:​deriving:​multiple|section]].+[[cpp:​syntax:​class:​deriving:​destructor|Définir les destructeurs dans une classe dérivée]]
  
  
  
cpp/syntax/class/deriving.1569306003.txt.gz · Last modified: 2019/09/24 06:20 by 127.0.0.1