Leçon 2 : Surcharge des opérateurs IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté
Leçon 2:Surcharge des opérateurs La surcharge Intérêt de la surcharge Règles de surcharge Opérateurs arithmétiques (classe vecteur) Opérateurs de redirection de flux Fonctions et classes amies
Méthode surchargée Le langage C++ permet la surcharge des méthodes, c’est à dire qu’il offre la possibilité d’implanter des méthodes ayant le même « nom ». La signature d ’une méthode regroupe son nom et le type de ses paramètres. Le type retour ne fait pas partie de la signature d ’une méthode.
Méthode surchargée : exemple Exemple d ’utilisation de la méthode : int i=power (2,3); double z=power(3.14,4); double z=power(2,3); Méthode power surchargée : int power (int x, int y); double power (double x, double y);
Méthode surchargée : résolution C’est la signature de la méthode qui permet au compilateur de sélectionner quelle méthode activer parmi celles surchargées. Les critères de sélection intervenant dans la résolution de surcharge sont : 1) La portée de la classe de l’instance qui déclenche l’appel. 2) Le nombre d’arguments dans l’appel. 3) La distance entre le type des arguments et celui des paramètres correspondant.
CLASSE VECTEUR On considère l ’objet : vecteur d ’entiers. Exemple : V = (2,5,1,4) V est un vecteur de 4 entiers. La dimension du vecteur a une valeur maximum égale à 10.
Classe vecteur : interface # include const int max=10; class vecteur{ public : vecteur(void); // constructeur vecteur (int t);// const et initialisation de la taille int getTaille(void); // Sélecteur => taille de IC void saisir (void); //saisie de IC void afficher(void);//Affichage de IC vecteur add (const vecteur&); // Est retourné : IC + argument void modifier(int i,int v); // T[i] <- v ~vecteur (void)// destructeur private : int taille; //nombre de cases réellement occupées int t[max]; //tableau de max entiers };
Classe vecteur : implantation int vecteur::getTaille(void){ return taille; } vecteur::vecteur(void){ taille=0; } vecteur::vecteur (int t){ taille = t; }
Classe vecteur : implantation void vecteur::saisir (void){ if (taille==0){ int ta; cout << "\n Taille du vecteur :"; cin >> ta; if (ta <= max) taille = ta; else taille=max;} for (int i=0; i<taille;i+=1){ cout<<"\n Valeur de l'élt No "<<i+1<< " : "; cin >> t[i]; } }
Classe vecteur : implantation void vecteur::afficher(void){ for (int i=0; i<taille;i+=1) { int no=i+1; cout <<"\n"<< no <<" : "; cout << t[i]; } }
Classe vecteur : implantation vecteur vecteur::add (const vecteur& v){ // IC + v vecteur somme; //appel du constructeur if (this->taille == v.taille){ somme.taille=this->taille; for (int i=0; i taille;i+=1){ somme.t[i]=this->t[i]+v.t[i]; } return (somme);//appel du construct par copie } void vecteur::modifier(int i,int v){ t[i]=v; }
SURCHARGE des OPERATEURS INTERÊTS : Facilité d’écriture Facilité de lecture Lisibilité BUT : Etendre la définition standard d ’un opérateur sur d’autres objets que ceux pour lesquels il est prédéfini. cout << V1+V2 # include"vecteur.h" void main (void) {vecteur V1 (6); vecteur V2 (6); cin >> V1>>V2;...
SURCHARGE des OPERATEURS Exemples : Opérations arithmétiques Opérateur << Opérateur >> Opérateurs de comparaison etc... # include"vecteur.h" void main (void) {vecteur V1 (6); vecteur V2 (6); cin >> V1>>V2;... cout << V1+V2
Règles Impossible de surcharger des opérateurs inconnus Impossible de modifier l ’arité des opérateurs (exemple :+ est binaire) Impossible de modifier les règles de priorité des opérateurs Impossible de redéfinir les opérateurs prédéfinis sur des types reconnus par l ’opérateur. Il faut respecter les règles syntaxiques prédéfinies
SURCHARGE de + Prototype retour operator symbole(paramètres) class X { public : X operator + (const X& B); // est retourné IC+B };
Surcharge de l ’opérateur + Toute méthode d ’une classe a un premier paramètre implicite représentant l ’instance courante. La surcharge d ’un opérateur par une fonction membre d ’une classe, implique donc que le premier paramètre représente l ’instance courante. Par conséquent l ’instance courante est toujours l ’opérande gauche des opérateurs binaires et l’unique opérande des opérateurs unaires. Appel de l ’opérateur (notation) : I1.operator + (I2); I1+I2;
Surcharge de l ’opérateur + # include class vecteur{ public : vecteur operator + (const vecteur& B); // est retourné : IC+B private : int taille; int t[max]; };
Surcharge de l ’opérateur + vecteur vecteur:: operator + (const vecteur& B) { vecteur somme; if (taille==B.taille) { somme.taille=taille; for (int i=0; i<taille;i+=1) somme.t[i]=t[i]+B.t[i]; } return somme; }
Surcharge des opérateurs >> et << Opérateur >> Constructeur Méthode La classe rectangle fournit des méthodes Une application # include # include "rectangle.h" void main (void) {rectangle R1,R2; } Opérateur << cin >> R1 >> R2; cout << R1 << R2;
# include # include "rectangle.h" void main (void) {rectangle R; cin >> R; cout << R;... Toute méthode est déclenchée par une instance Opérateurs de redirection de flux L ’instance cin de la classe istream déclenche l ’opérateur >> L ’instance cout de la classe ostream déclenche l ’opérateur <<
Problème d ’accessibilité Problème Pour écrire : cin >> R; il faut que la classe istream puisse accéder à la section private de la classe rectangle. Résolution Déclarer la méthode de surcharge de l ’opérateur >> comme fonction amie de la classe rectangle.
Méthode amie Mécanisme : Lorsqu ’une méthode externe à une classe C est déclarée amie dans la classe C, alors tous les membres de la classe C (y compris ceux de la section private ) sont accessibles par la fonction externe. Syntaxe : Qualificateur friend placé devant le prototype de la méthode externe à la classe.
CLASSE AMIE class X { public : friend class Y; private : }; EFFET Toutes les méthodes de la classe Y peuvent accéder à la section private de la classe X C ’est moi : classe X qui définit qui sont mes ami(e)s, et donc qui ouvre l ’accès de ma section private à l ’extérieur.
PROTOTYPE : opérateur >> class rectangle {public : friend istream& operator >> ( ???); Dans la classe istream l ’opérateur >> retourne une référence sur le flux Référence notée : istream&
PROTOTYPE : opérateur >> class rectangle {public : //IC est de type istream friend istream& operator>>( istream& f,rectangle& R); // longueur et largeur de R sont saisies Rectangle à saisir Afin de pouvoir enchaîner les appels : cin >> R1 >> R2; l ’opérateur retourne une référence sur le flux qu ’elle a reçu en premier argument Le premier argument est toujours une référence sur IC
IMPLANTATION : opérateur >> istream& operator>>(istream& flux,rectangle& R);{ if (taille==0){ int ta; cout << "\n Taille du vecteur :"; flux >> ta; if (ta <= max) taille = ta; else taille=max; } for (int i=0; i<taille;i+=1){ cout<<"\n Valeur de l'élt No "<<i+1<< " : "; flux >> t[i]; } return flux; }
CLASSE VECTEUR On considère l ’objet : vecteur d ’entiers. Exemple : V = (2,5,1,4) V est un vecteur de 4 entiers. La dimension du vecteur a une valeur maximum égale à 10. Exercice Coder une application permettant d ’exécuter la fonction main suivante # include <iostream.h> # include "vecteur.h" void main (void) { vecteur V(4); cin >> V; cout << V; }