User Tools

Site Tools


in204:cpp:syntax:class:deriving

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
in204:cpp:syntax:class:deriving [2021/03/28 10:09]
bmonsuez [Déclarer des méthodes dans une classe dérivée]
in204:cpp:syntax:class:deriving [2022/11/18 10:51] (current)
Line 120: Line 120:
 En effet, lorsque 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. En effet, lorsque 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.
  
-===== Définition d'une classe dérivée ​====+[[cpp:​syntax:​class:​deriving:​creating|Définir ​une classe dérivée]]
  
-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.+[[cpp:​syntax:​class:​deriving:​methods|Définir champs et méthodes dans une classe dérivée]]
  
-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.+[[cpp:​syntax:​class:​deriving:​constructor|Définir ​les constructeurs dans une classe ​dérivée]]
  
-===== Déclaration d'une classe dérivée ​====+[[cpp:​syntax:​class:​deriving:​destructor|Définir les destructeurs dans une classe dérivée]]
  
-La syntaxe pour déclarer une classe comme héritant d'une classe de base est la suivante : 
-<code cpp> 
  
-class DerivingClass:​ public BaseClass +===== Déclarer des champs dans une classe dérivée =====
-+
-};+
  
 +Les champs qui sont déclarés dans une classe dérivée ne peuvent pas avoir le même nom que les champs dans une des classes de base.
 +
 +===== Déclarer des méthodes dans une classe dérivée =====
 +
 +__**Cas 1**: La méthode ''​method''​ a un nom différent de celui des méthodes existance dans la classe de base.__
 +
 +C'est par exemple le cas de la méthode ''​previous()''​ dans la classe ''​bidi_enumerate_characters''​ :
 +<code cpp>
 +  int previous()
 +  {
 +      return mReversePosition >= 0 ? 
 +        (int)mString[mPosition++] : -1;
 +  }
 </​code>​ </​code>​
  
-==== Accessibilité ​des méthodes ​et des champs d'une classe de base ====+Ce sont les règles habituelles de la déclaration ​des méthodes ​dans les classes. La nouvelle méthode s'ajoute aux anciennes méthodes.
  
-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.+__**Cas 2**: La méthode ​''​method'' ​a le même nom que celui des méthodes ​existance ​dans la classe de base.__
  
-^ Déclaration dans la classe ​de base ^ Accesibilité dans la classe dérivée ^  +C'est par exemple le cas de la méthode ​''​reset()''​ dans la classe ''​bidi_enumerate_characters'' ​
-|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 | +<code cpp> 
-|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 | +  void reset() 
-|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 |+  { 
 +      mPosition = 0; 
 +      enumerate_characters()::​reset();​ 
 +  } 
 +</​code>​
  
-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''​.+**Règle 1**: Si nous définissons une ou plusieurs méthodes ayant le nom ''​method'' ​et que des méthodes ayant le même nom ont été définies dans la classe ​de baseles méthodes ayant comme nom ''​method'' ​sont cachées dans la classe de base
  
-^ Attribut d'​héritage ^ Accessibilité en dehors de la classe ^ Accessibilité dans une classe dérivant de ''​DerivingClass''​ ^ +<code cpp> 
-|''​DerivingClasspublic 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. | +class enumerate_characters 
-|''​DerivingClassprivate 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. | +
-|''​DerivingClassprotected 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. |+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 extended_enumerate_characters:​ enumerate_characters
 +{
 +public:
 +  extended_enumerate_characters(const char* aString, int theNumberOfCharacters):​
 +      enumerate_characters(aString,​ theNumberOfCharacters) {}
 +  ​
 +  int next(int lookup)
 +  {
 +      mPosition += increment;
 +      if(mPosition >= mNumberOfCharacters)
 +      {
 +          mPosition = mNumberOfCharacters;​
 +          return (int)-1;
 +      }
 +      return (int)mString[mPosition++];​
 +  }
 +}
 +</​code>​
  
-===== Déclarer des champs ​dans une classe ​dérivée =====+Dans ce cas, la méthode ''​next(int)''​ va être la seule méthode visible ​dans la classe ​ ''​extended_enumerate_characters''​. La méthode ''​next()''​ de la classe ''​enumerate_characters''​ mais elle sera masquée et sera donc inaccessible.
  
-Les champs qui sont déclarés ​dans une classe dérivée ne peuvent ​pas avoir le même nom que les champs ​dans une des classes de base.+**Règle 2**: Il est possible de rendre visible ​dans la classe dérivée ​les méthodes qui ont été définies dans la classe de base est qui ne prennent ​pas les même arguments ​que celles définies ​dans la classe dérivée.
  
-===== Déclarer des méthodes dans une classe dérivée ​=====+Si nous voulons rendre la méthode ''​next()''​ visible, il faudra ajouter à la classe ''​extended_enumerate_characters''​ la directive : ''​using enumerate_characters::​next''​ pour indiquer que les méthodes ​ayant pour nom ''​next''​ et étant définie dans la classe de base sont aussi visible ​dans la classe dérivée
 +<code cpp> 
 +class extended_enumerate_characters:​ enumerate_characters 
 +
 +public: 
 +  extended_enumerate_characters(const char* aString, int theNumberOfCharacters):​ 
 +      enumerate_characters(aString,​ theNumberOfCharacters) {}
  
-__**Cas 1**La méthode ''​method''​ a un nom différent de celui des méthodes existance dans la classe de base.__+  using enumerate_characters::next; 
 +  int next(int lookup) 
 +  { 
 +      mPosition += increment;​ 
 +      if(mPosition >= mNumberOfCharacters) 
 +      { 
 +          mPosition = mNumberOfCharacters;​ 
 +          return (int)-1; 
 +      } 
 +      return (int)mString[mPosition++];​ 
 +  } 
 +
 +</​code>​
  
- +Dans la classe ''​extended_enumerate_characters'',​ les deux méthodes ''​enumerate_characters::​next()''​ et  
 +''​extended_enumerate_characters::​next(int)''​ sont accessibles.  
 + 
 +<code cpp> 
 +    extended_enumerate_characters enumerator("​abcdefg"​);​ 
 +    std::cout << enumerator.next(2);​ 
 +    std::cout << enumerator.next();​ 
 +</​code>​
  
 +Par contre, dans la classe ''​bidi_enumerate_characters'',​ ajouter ''​using enumerate_characters::​reset''​ ne sert à rien parce que la fonction ''​reset()''​ dans la classe dérivée à la [[cpp::​syntax::​functions::​overload|même signature]] que la fonction ''​reset''​ dans la classe de base.
  
in204/cpp/syntax/class/deriving.1616926188.txt.gz · Last modified: 2021/03/28 10:09 by bmonsuez