SlideShare une entreprise Scribd logo

Chapitre6: Surcharge des opérateurs

Aziz Darouichi
Aziz Darouichi
Aziz DarouichiAssociate Professor à FST Marrakech

Voici le chapitre sur la surcharge des opérateurs en C++. Si vous avez des remarques ou suggestions afin de le parfaire. N’hésitez pas à me contacter via mon email: pr.azizdarouichi@gmail.com. Bonne lecture

Chapitre6: Surcharge des opérateurs

1  sur  62
Télécharger pour lire hors ligne
Aziz DAROUICHI
1
Programmation Orientée Objet en C++:
Surcharge des opérateurs
2
Contexte
Exemples d’appels d’opérateurs
Surcharge (ou surdéfinition) de fonction
Surcharge interne et surcharge externe
Fonctions amies
Surcharge externe et friendship
Les opérateurs de comparaison
Lien entre opérateurs
Surcharge interne ou Surcharge externe?
Surcharges de quelques opérateurs usuels
Pourquoi const en type de retour ?
Pourquoi operator<< retourne-t-il un ostream& ?
Quel type de retour pour operator+= ?
Surcharge de l’opérateur d’affectation
Q & A
Contexte
Exemples d’appels d’opérateurs
Surcharge (ou surdéfinition) de fonction
Surcharge interne et surcharge externe
Fonctions amies
Surcharge externe et friendship
Les opérateurs de comparaison
Lien entre opérateurs
Surcharge interne ou Surcharge externe?
Surcharges de quelques opérateurs usuels
Pourquoi const en type de retour ?
Pourquoi operator<< retourne-t-il un ostream& ?
Quel type de retour pour operator+= ?
Surcharge de l’opérateur d’affectation
Q & A
Chapitre 6: Surcharge des opérateurs
2
Exemple (1/2):
class Complexe{
private:
double real;
double img;
public:
Complexe(double a, double b): real(a), img(b){}
Complexe(): Complexe(0.0, 0.0){}
//add(): méthode d’instance qui additionne 2 nombres complexes
Complexe add(Complexe const&c) {
Complexe s;
s.real = real+c.real;
s.img = real+c.img;
return s;
}
void afficher() {
cout << "Nombre complexe: " << real << " ," << img << endl;
}
};
33
Contexte
Exemple (2/2):
Output:
Nombre complexe: 4.5, 6.5
Nombre complexe: 9, 12.3
int main(){
Complexe z1(1.5, 2.5), z2(3, 4), z3(4.5, 5.8), z4, z5;
z4 = z1.add(z2);
z4.afficher();
z5 = z1.add(z2.add(z3));
z5.afficher();
}
44
Contexte
Il est quand même plus naturel d’écrire :
z4 = z1 + z2 ; //que z4 = z1.add(z2);
z5 = z1 + z2 + z3; //que z3 = z1.add(z2.add(z3));
De même, on préfèrera unifier l’affichage :
cout << "z3 = " << z3 << endl;
plutôt que d’écrire :
cout << "z3 = ";
z3.afficher();
cout << endl;
55
Contexte
a + b operator+(a, b) ou a.operator+(b)
b + a operator+(b, a) ou b.operator+(a)
-a operator-(a) ou a.operator-()
cout << a operator<<(cout, a) ou cout.operator<<(a)
a = b a.operator=(b)
a += b operator+=(a, b) ou a.operator+=(b)
++a operator++(a) ou a.operator++()
not a operator not(a) ou a.operator not()
ou operator!(a) ou a.operator!()
66
Exemples d’appels d’opérateurs
Publicité

Recommandé

Chapitre5: Classes et objets
Chapitre5: Classes et objetsChapitre5: Classes et objets
Chapitre5: Classes et objetsAziz Darouichi
 
Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références Aziz Darouichi
 
Chapitre2fonctionscppv2019
Chapitre2fonctionscppv2019Chapitre2fonctionscppv2019
Chapitre2fonctionscppv2019Aziz Darouichi
 
Partie 11: Héritage — Programmation orientée objet en C++
Partie 11: Héritage — Programmation orientée objet en C++Partie 11: Héritage — Programmation orientée objet en C++
Partie 11: Héritage — Programmation orientée objet en C++Fabio Hernandez
 
Chap1V2019: Cours en C++
Chap1V2019: Cours en C++Chap1V2019: Cours en C++
Chap1V2019: Cours en C++Aziz Darouichi
 
Chapitre3TableauxEnCppV2019
Chapitre3TableauxEnCppV2019Chapitre3TableauxEnCppV2019
Chapitre3TableauxEnCppV2019Aziz Darouichi
 

Contenu connexe

Tendances

Cours structures des données (langage c)
Cours structures des données (langage c)Cours structures des données (langage c)
Cours structures des données (langage c)rezgui mohamed
 
FormationPython2019.pptx
FormationPython2019.pptxFormationPython2019.pptx
FormationPython2019.pptxLamissGhoul1
 
Cours Programmation Orientée Objet en C++
Cours Programmation Orientée Objet en C++Cours Programmation Orientée Objet en C++
Cours Programmation Orientée Objet en C++Amina HAMEURLAINE
 
Correction de td poo n2
Correction de td poo n2Correction de td poo n2
Correction de td poo n2yassine kchiri
 
Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI
Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI
Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI Mansouri Khalifa
 
resume algo 2023.pdf
resume algo 2023.pdfresume algo 2023.pdf
resume algo 2023.pdfsalah fenni
 
Partie 9: Fonctions Membres — Programmation orientée objet en C++
Partie 9: Fonctions Membres — Programmation orientée objet en C++Partie 9: Fonctions Membres — Programmation orientée objet en C++
Partie 9: Fonctions Membres — Programmation orientée objet en C++Fabio Hernandez
 
Atelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El HassaniAtelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El HassaniShellmates
 
Introduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonIntroduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonAbdoulaye Dieng
 
Exercice 1 java Héritage
Exercice 1 java HéritageExercice 1 java Héritage
Exercice 1 java HéritageNadaBenLatifa
 
La programmation modulaire en Python
La programmation modulaire en PythonLa programmation modulaire en Python
La programmation modulaire en PythonABDESSELAM ARROU
 
Partie 8: Objets et Classes — Programmation orientée objet en C++
Partie 8: Objets et Classes — Programmation orientée objet en C++Partie 8: Objets et Classes — Programmation orientée objet en C++
Partie 8: Objets et Classes — Programmation orientée objet en C++Fabio Hernandez
 
programmation orienté objet c++
programmation orienté objet c++programmation orienté objet c++
programmation orienté objet c++coursuniv
 

Tendances (20)

Cours c++
Cours c++Cours c++
Cours c++
 
Chapitre3 tableauxcpp
Chapitre3 tableauxcppChapitre3 tableauxcpp
Chapitre3 tableauxcpp
 
Cours structures des données (langage c)
Cours structures des données (langage c)Cours structures des données (langage c)
Cours structures des données (langage c)
 
02 correction-td smi-s3-algo2
02 correction-td smi-s3-algo202 correction-td smi-s3-algo2
02 correction-td smi-s3-algo2
 
FormationPython2019.pptx
FormationPython2019.pptxFormationPython2019.pptx
FormationPython2019.pptx
 
COURS_PYTHON_22.ppt
COURS_PYTHON_22.pptCOURS_PYTHON_22.ppt
COURS_PYTHON_22.ppt
 
Cours Programmation Orientée Objet en C++
Cours Programmation Orientée Objet en C++Cours Programmation Orientée Objet en C++
Cours Programmation Orientée Objet en C++
 
Correction de td poo n2
Correction de td poo n2Correction de td poo n2
Correction de td poo n2
 
Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI
Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI
Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI
 
resume algo 2023.pdf
resume algo 2023.pdfresume algo 2023.pdf
resume algo 2023.pdf
 
Partie 9: Fonctions Membres — Programmation orientée objet en C++
Partie 9: Fonctions Membres — Programmation orientée objet en C++Partie 9: Fonctions Membres — Programmation orientée objet en C++
Partie 9: Fonctions Membres — Programmation orientée objet en C++
 
Atelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El HassaniAtelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El Hassani
 
Cours compilation
Cours compilationCours compilation
Cours compilation
 
Chapitre 4 Java script
Chapitre 4 Java scriptChapitre 4 Java script
Chapitre 4 Java script
 
Cours langage-c
Cours langage-cCours langage-c
Cours langage-c
 
Introduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonIntroduction à l’orienté objet en Python
Introduction à l’orienté objet en Python
 
Exercice 1 java Héritage
Exercice 1 java HéritageExercice 1 java Héritage
Exercice 1 java Héritage
 
La programmation modulaire en Python
La programmation modulaire en PythonLa programmation modulaire en Python
La programmation modulaire en Python
 
Partie 8: Objets et Classes — Programmation orientée objet en C++
Partie 8: Objets et Classes — Programmation orientée objet en C++Partie 8: Objets et Classes — Programmation orientée objet en C++
Partie 8: Objets et Classes — Programmation orientée objet en C++
 
programmation orienté objet c++
programmation orienté objet c++programmation orienté objet c++
programmation orienté objet c++
 

Similaire à Chapitre6: Surcharge des opérateurs

Les fonctions lambdas en C++11 et C++14
Les fonctions lambdas en C++11 et C++14Les fonctions lambdas en C++11 et C++14
Les fonctions lambdas en C++11 et C++14Aurélien Regat-Barrel
 
Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1Laurent BUNIET
 
Scala : programmation fonctionnelle
Scala : programmation fonctionnelleScala : programmation fonctionnelle
Scala : programmation fonctionnelleMICHRAFY MUSTAFA
 
Fonctions_Inline_Amies en C++
Fonctions_Inline_Amies en C++Fonctions_Inline_Amies en C++
Fonctions_Inline_Amies en C++ANOUAR HAKIM
 
Interception de signal avec dump de la pile d'appel
Interception de signal avec dump de la pile d'appelInterception de signal avec dump de la pile d'appel
Interception de signal avec dump de la pile d'appelThierry Gayet
 
JAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVAJAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVAAymen Bedwivski
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaAmel Morchdi
 
System c eniso_jan_fev_07
System c eniso_jan_fev_07System c eniso_jan_fev_07
System c eniso_jan_fev_07haythem_2015
 
Javascript ne se limite pas à jquery
Javascript ne se limite pas à jqueryJavascript ne se limite pas à jquery
Javascript ne se limite pas à jqueryneuros
 
Marzouk une introduction à jdbc
Marzouk une introduction à jdbcMarzouk une introduction à jdbc
Marzouk une introduction à jdbcabderrahim marzouk
 
20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soat20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soatSOAT
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logiciellecyrilgandon
 
Chapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en JavaChapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en JavaAziz Darouichi
 

Similaire à Chapitre6: Surcharge des opérateurs (20)

Ch07
Ch07Ch07
Ch07
 
Ch06
Ch06Ch06
Ch06
 
Les fonctions lambdas en C++11 et C++14
Les fonctions lambdas en C++11 et C++14Les fonctions lambdas en C++11 et C++14
Les fonctions lambdas en C++11 et C++14
 
Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1
 
Scala : programmation fonctionnelle
Scala : programmation fonctionnelleScala : programmation fonctionnelle
Scala : programmation fonctionnelle
 
POO-chapitre3.pptx
POO-chapitre3.pptxPOO-chapitre3.pptx
POO-chapitre3.pptx
 
Fonctions_Inline_Amies en C++
Fonctions_Inline_Amies en C++Fonctions_Inline_Amies en C++
Fonctions_Inline_Amies en C++
 
Interception de signal avec dump de la pile d'appel
Interception de signal avec dump de la pile d'appelInterception de signal avec dump de la pile d'appel
Interception de signal avec dump de la pile d'appel
 
Ch03
Ch03Ch03
Ch03
 
JAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVAJAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVA
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 java
 
System c eniso_jan_fev_07
System c eniso_jan_fev_07System c eniso_jan_fev_07
System c eniso_jan_fev_07
 
Javascript ne se limite pas à jquery
Javascript ne se limite pas à jqueryJavascript ne se limite pas à jquery
Javascript ne se limite pas à jquery
 
Marzouk une introduction à jdbc
Marzouk une introduction à jdbcMarzouk une introduction à jdbc
Marzouk une introduction à jdbc
 
POO
POOPOO
POO
 
20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soat20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soat
 
Chapitre 04 : les fonctions
Chapitre 04 : les fonctionsChapitre 04 : les fonctions
Chapitre 04 : les fonctions
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logicielle
 
Chapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en JavaChapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en Java
 
Part1
Part1Part1
Part1
 

Plus de Aziz Darouichi

Chapitre 2: String en Java
Chapitre 2:  String en JavaChapitre 2:  String en Java
Chapitre 2: String en JavaAziz Darouichi
 
Chapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En JavaChapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En JavaAziz Darouichi
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfacesAziz Darouichi
 
Chapitre1: Langage Python
Chapitre1: Langage PythonChapitre1: Langage Python
Chapitre1: Langage PythonAziz Darouichi
 
Cours Visual Basic.NET
Cours Visual Basic.NETCours Visual Basic.NET
Cours Visual Basic.NETAziz Darouichi
 

Plus de Aziz Darouichi (8)

Chapitre 2: String en Java
Chapitre 2:  String en JavaChapitre 2:  String en Java
Chapitre 2: String en Java
 
Chapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En JavaChapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En Java
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfaces
 
Partie3BI-DW-OLAP2019
Partie3BI-DW-OLAP2019Partie3BI-DW-OLAP2019
Partie3BI-DW-OLAP2019
 
Partie2BI-DW2019
Partie2BI-DW2019Partie2BI-DW2019
Partie2BI-DW2019
 
Partie1BI-DW2019
Partie1BI-DW2019Partie1BI-DW2019
Partie1BI-DW2019
 
Chapitre1: Langage Python
Chapitre1: Langage PythonChapitre1: Langage Python
Chapitre1: Langage Python
 
Cours Visual Basic.NET
Cours Visual Basic.NETCours Visual Basic.NET
Cours Visual Basic.NET
 

Dernier

Shelly Qubini Dry Contact Module Z-Wave Manual
Shelly Qubini Dry Contact Module Z-Wave ManualShelly Qubini Dry Contact Module Z-Wave Manual
Shelly Qubini Dry Contact Module Z-Wave ManualDomotica daVinci
 
JDN 2023 les applications de l'impression 3D.pdf
JDN 2023 les applications de l'impression 3D.pdfJDN 2023 les applications de l'impression 3D.pdf
JDN 2023 les applications de l'impression 3D.pdfAlexandre Contat
 
Pour une Autorité française de l’Intelligence Artificielle (IA)
Pour une Autorité française de l’Intelligence Artificielle (IA)Pour une Autorité française de l’Intelligence Artificielle (IA)
Pour une Autorité française de l’Intelligence Artificielle (IA)benj_2
 
Wave_Shutter_user_guide_multilang_print_V3.pdf
Wave_Shutter_user_guide_multilang_print_V3.pdfWave_Shutter_user_guide_multilang_print_V3.pdf
Wave_Shutter_user_guide_multilang_print_V3.pdfDomotica daVinci
 
Débrief CES 2024 by Niji
Débrief CES 2024 by NijiDébrief CES 2024 by Niji
Débrief CES 2024 by NijiNiji
 
Extr4.0rdinaire - L'IA, on y va ! - 15/02/2024
Extr4.0rdinaire - L'IA, on y va ! - 15/02/2024Extr4.0rdinaire - L'IA, on y va ! - 15/02/2024
Extr4.0rdinaire - L'IA, on y va ! - 15/02/2024Infopole1
 

Dernier (6)

Shelly Qubini Dry Contact Module Z-Wave Manual
Shelly Qubini Dry Contact Module Z-Wave ManualShelly Qubini Dry Contact Module Z-Wave Manual
Shelly Qubini Dry Contact Module Z-Wave Manual
 
JDN 2023 les applications de l'impression 3D.pdf
JDN 2023 les applications de l'impression 3D.pdfJDN 2023 les applications de l'impression 3D.pdf
JDN 2023 les applications de l'impression 3D.pdf
 
Pour une Autorité française de l’Intelligence Artificielle (IA)
Pour une Autorité française de l’Intelligence Artificielle (IA)Pour une Autorité française de l’Intelligence Artificielle (IA)
Pour une Autorité française de l’Intelligence Artificielle (IA)
 
Wave_Shutter_user_guide_multilang_print_V3.pdf
Wave_Shutter_user_guide_multilang_print_V3.pdfWave_Shutter_user_guide_multilang_print_V3.pdf
Wave_Shutter_user_guide_multilang_print_V3.pdf
 
Débrief CES 2024 by Niji
Débrief CES 2024 by NijiDébrief CES 2024 by Niji
Débrief CES 2024 by Niji
 
Extr4.0rdinaire - L'IA, on y va ! - 15/02/2024
Extr4.0rdinaire - L'IA, on y va ! - 15/02/2024Extr4.0rdinaire - L'IA, on y va ! - 15/02/2024
Extr4.0rdinaire - L'IA, on y va ! - 15/02/2024
 

Chapitre6: Surcharge des opérateurs

  • 1. Aziz DAROUICHI 1 Programmation Orientée Objet en C++: Surcharge des opérateurs
  • 2. 2 Contexte Exemples d’appels d’opérateurs Surcharge (ou surdéfinition) de fonction Surcharge interne et surcharge externe Fonctions amies Surcharge externe et friendship Les opérateurs de comparaison Lien entre opérateurs Surcharge interne ou Surcharge externe? Surcharges de quelques opérateurs usuels Pourquoi const en type de retour ? Pourquoi operator<< retourne-t-il un ostream& ? Quel type de retour pour operator+= ? Surcharge de l’opérateur d’affectation Q & A Contexte Exemples d’appels d’opérateurs Surcharge (ou surdéfinition) de fonction Surcharge interne et surcharge externe Fonctions amies Surcharge externe et friendship Les opérateurs de comparaison Lien entre opérateurs Surcharge interne ou Surcharge externe? Surcharges de quelques opérateurs usuels Pourquoi const en type de retour ? Pourquoi operator<< retourne-t-il un ostream& ? Quel type de retour pour operator+= ? Surcharge de l’opérateur d’affectation Q & A Chapitre 6: Surcharge des opérateurs 2
  • 3. Exemple (1/2): class Complexe{ private: double real; double img; public: Complexe(double a, double b): real(a), img(b){} Complexe(): Complexe(0.0, 0.0){} //add(): méthode d’instance qui additionne 2 nombres complexes Complexe add(Complexe const&c) { Complexe s; s.real = real+c.real; s.img = real+c.img; return s; } void afficher() { cout << "Nombre complexe: " << real << " ," << img << endl; } }; 33 Contexte
  • 4. Exemple (2/2): Output: Nombre complexe: 4.5, 6.5 Nombre complexe: 9, 12.3 int main(){ Complexe z1(1.5, 2.5), z2(3, 4), z3(4.5, 5.8), z4, z5; z4 = z1.add(z2); z4.afficher(); z5 = z1.add(z2.add(z3)); z5.afficher(); } 44 Contexte
  • 5. Il est quand même plus naturel d’écrire : z4 = z1 + z2 ; //que z4 = z1.add(z2); z5 = z1 + z2 + z3; //que z3 = z1.add(z2.add(z3)); De même, on préfèrera unifier l’affichage : cout << "z3 = " << z3 << endl; plutôt que d’écrire : cout << "z3 = "; z3.afficher(); cout << endl; 55 Contexte
  • 6. a + b operator+(a, b) ou a.operator+(b) b + a operator+(b, a) ou b.operator+(a) -a operator-(a) ou a.operator-() cout << a operator<<(cout, a) ou cout.operator<<(a) a = b a.operator=(b) a += b operator+=(a, b) ou a.operator+=(b) ++a operator++(a) ou a.operator++() not a operator not(a) ou a.operator not() ou operator!(a) ou a.operator!() 66 Exemples d’appels d’opérateurs
  • 7. Surcharge (ou surdéfinition) de fonction 7 Rappel: Deux fonctions ayant le même nom mais pas les mêmes paramètres. Exemple : int max(int, int); double max(double, double); De la même façon, on va pouvoir écrire plusieurs fonctions pour les opérateurs; Exemple : Complexe operator+(Complexe, Complexe); Matrice operator+(Matrice, Matrice); 7
  • 8. Surcharge interne et surcharge externe 8 La surcharge des opérateurs peut être réalisée soit à l’extérieur (par des fonctions), Complexe operator+(Complexe, Complexe); soit à l’intérieur (par des méthodes) class Complexe{ public: Complexe operator+(Complexe) const; }; de la classe à laquelle ils s’appliquent. 8
  • 9. Surcharge externe 9 Vu que les attributs sont privés et donc inaccessibles depuis l'extérieur de la classe. Il existe trois solutions pour la surcharge externe des opérateurs: via des accesseurs, via une autre méthode créée dans la classe, via le concept d’amitié. 9
  • 10. Surcharge externe 10 Exemple (1/2): 10 class Complexe{ private: double real; double img; public: Complexe(double a, double b): real(a), img(b){} Complexe(): Complexe(0.0, 0.0){} void afficher() const{ cout << "Nombre complexe: " << real << " ," << img << endl;} double getReal() const { return real;} double getImg() const { return img;} };//Fin de la classe const Complexe operator+(Complexe const& z1, Complexe const& z2){ Complexe z3( z1.getReal() + z2.getReal(), z1.getImg() + z2.getImg() ); return z3; }
  • 11. Exemple (2/2): Output: Nombre complexe: 4.5, 6.5 Nombre complexe: 9, 10.3 int main(){ Complexe z1(1.5, 2.5), z2(3, 4), z3(4.5, 5.8), z4, z5; z4 = z1+z2; z4.afficher(); z5 = z1+z2+z3; z5.afficher(); } 1111 Surcharge externe
  • 12. Choix du prototype Base : Complexe operator+(Complexe z1, Complexe z2); Optimisation : 1. Complexe operator+(Complexe const& z1, Complexe const& z2); 2. Complexe& operator+(Complexe const& z1, Complexe const& z2); 3. const Complexe operator+(Complexe const& z1, Complexe const& z2); C++11: const Complexe operator+(Complexe z1, Complexe const& z2); 1212 Surcharge externe
  • 13. Les opérateurs de flux Exemple: cout << z1; operator<<(cout, z1); Le prototype est: ostream& operator<<(ostream&, Complexe const&); Le paramètre ostream est passé par référence, On passe le deuxième paramètre par référence constante, vu que l’on ne fait qu'afficher le contenu de ce paramètre et rien d’autre. Le type de retour est une référence sur l’objet ostream, ce qui permet de faire une chaîne : cout << z1 << z2 << z3; 1313 Surcharge externe
  • 14. Définitions de l’opérateur d’affichage Via des accesseurs : ostream& operator<<(ostream& sortie, Complexe const& z){ sortie << "( " << z.getReal() << ", " << z.getImg() << ")" ; return sortie; } 1414 Surcharge externe
  • 15. Définitions de l’opérateur d’affichage Via des accesseurs : 1515 Surcharge externe class Complexe{ private: double real; double img; public: … double getReal() const { return real;} double getImg() const { return img;} }; //Fin de la classe ostream& operator<<(ostream& sortie, Complexe const& z){ sortie << "( " << z.getReal() << ", " << z.getImg() << ")" ; return sortie; } int main(){ Complexe z1(1.5, 2.5); cout << z1; //affiche: (1.5, 2.5) }
  • 16. Définitions de l’opérateur d’affichage Via une autre méthode : ostream& operator<<(ostream& sortie, Complexe const& z){ return z.afficher(sortie); } avec ostream& afficher(ostream& flux){ flux << "( " << real << ", " << img << ")" ; return flux; } 1616 Surcharge externe
  • 17. Définitions de l’opérateur d’affichage Via une autre méthode : 1717 Surcharge externe class Complexe{ private: double real; double img; public: … double getReal() const { return real;} double getImg() const { return img;} ostream& afficher(ostream& flux){ //afficher() est une méthode d’instance flux << "( " << real << ", " << img << ")" ; return flux; } }; //Fin de la classe ostream& operator<<(ostream& sortie, Complexe const& z){ return z.afficher(sortie); } int main(){ Complexe z1(1.5, 2.5); cout << z1; //affiche: (1.5, 2.5) }
  • 18. Définitions de l’opérateur d’affichage Via le concept d'amitié 1818 Surcharge externe
  • 19. Une fonction membre a accès aux membres publics et privés de la classe. Une classe avait généralement des membres privés (principe d’encapsulation), et que ceux-ci n’étaient pas accessibles par des fonctions non-membres. Dans certains cas, cependant, on souhaite pouvoir utiliser une fonction qui puisse accéder aux membres d’une classe, sans toutefois nécessairement disposer d’une instance de cette classe par laquelle l’appeler. Fonctions amies 19
  • 20. Une fonction amie d’une classe est une fonction qui, sans être membre de cette classe, a le droit d’accéder à tous ses membres. Une fonction est l’amie (friend) d’une classe lorsqu’elle est autorisée à adresser directement les membres privés de cette classe. L'amitié est déclarée en utilisant le mot-clé réservé: friend Il importe peu de déclarer une fonction amie dans la partie public ou private d'une classe donnée. Dans les deux cas, la fonction sera vue comme étant une fonction public. Fonctions amies 20
  • 21. Exemple: La fonction afficher() est une fonction amie de la classe Tableau. Déclarer la fonction afficher() private ou public importe peu. Fonctions amies class Tableau{ private: int nbr; // la taille du tableau tab double* tab; // pointeur vers un tableau de double friend void afficher(const Tableau &); public: Tableau(int nbrElements); ... }; 21 void afficher(const Tableau &t){ cout << "["; for (int i(0); i < t.nbr; i++) cout << " " << t.tab[i]; cout << "]" ; }
  • 22. Friend Parfois, il peut être nécessaire d’autoriser les opérateurs externes d’accéder à certains éléments private. Dans ce cas, ajoutez, dans la définition de la classe, leur prototype précédé du mot clé friend : friend const Complexe operator*(double, Complexe const&); friend ostream& operator<<(ostream&, Complexe const&); Le mot clé friend signifie que ces fonctions, bien que ne faisant pas partie de la classe, peuvent avoir accès aux attributs et méthodes private de la classe. Les définitions restent hors de la classe (et sans le mot clé friend). 2222 Surcharge externe et friendship
  • 23. Exemple (1/2): class Complexe{ friend ostream& operator<<(ostream& sortie, Complexe const& z); //Notez la présence //de friend private: double real; double img; public: Complexe(double a, double b): real(a), img(b){} Complexe(): Complexe(0.0, 0.0) {} }; //Fin de la classe ostream& operator<<(ostream& sortie, Complexe const& z){ sortie << "(" << z.real << ", " << z.img << ")"; return sortie; } 2323 Surcharge externe et friendship
  • 24. Exemple (2/2): int main(){ Complexe z(1.5, 2.5); cout << z; return 0; } Output: (1.5, 2.5) 2424 Surcharge externe et friendship
  • 25. 2525 Surcharge externe et friendship L’opérateur de flux >> On va surcharger l’opérateur >> pour la classe Complexe. Voici le prototype de cet opérateur: istream& operator>>(istream&, Complexe & ); Le paramètre istream est passé par référence, Le deuxième paramètre est passé par référence, il représente le nombre complexe à définir. Le type de retour est une référence sur istream, ce qui permet de faire une chaîne : cin >> z1 >> z2;
  • 26. 2626 Surcharge de l’opérateur de flux >> Exemple (1/2): class Complexe{ friend ostream& operator<<(ostream& sortie, Complexe const& z); //surcharge de l'opérateur << friend istream& operator>>(istream& flux, Complexe& z); //surcharge de l'opérateur >> private: double real; double img; public: Complexe(double a, double b): real(a), img(b){} Complexe(): Complexe(0.0, 0.0) {} }; //Fin de la classe ostream& operator<<(ostream& sortie, Complexe const& z){ sortie << "(" << z.real << ", " << z.img << ")"; return sortie;} istream& operator>>(istream& flux, Complexe & z){ cout << "Partie réelle ?" << endl; flux >> z.real; cout << "Partie imaginaire ?" << endl; flux >> z.img; return flux; }
  • 27. 2727 Surcharge de l’opérateur de flux >> Exemple (2/2): int main(){ Complexe z; cin >> z; cout << z; return 0; } Output: Partie réelle ? 3.5 Partie imaginaire ? 4.5 (3.5, 4.5)
  • 28. Les opérateurs de comparaison On va surcharger les opérateurs de comparaison (==, !=, <, >=,...) Voici le prototype de ces opérateurs: bool operatorOp(NomDeLaClasse const&obj1, NomDeLaClasse const& obj2); 2828 Surcharge externe
  • 29. Operateur == Commençons par l'opérateur de test d'égalité ==. Pour être capables d'utiliser le symbole « == » entre deux objets, vous devez créer une fonction ayant précisément pour nom operator==et dotée du prototype : bool operator==(Complexe const& a, Complexe const& b); Mode d'utilisation if (z1 == z2){ std::cout << "Les deux nombres complexes sont égaux !" << std::endl; } 2929 Les opérateurs de comparaison
  • 30. L'implémentation de l'opérateur== 1ère solution avec friend Voici la définition de la fonction operator==: bool operator== (Complexe const& a, Complexe const& b){ if (a.real == b.real && a.img == b. img) return true; else return false; } Ou directement bool operator== (Complexe const& a, Complexe const& b){ return (a.real == b.real && a.img == b. img); } 3030 Les opérateurs de comparaison
  • 31. L'implémentation de l'opérateur== 1ère solution avec friend Dans la définition de la classe, vous ajoutez le prototype de l’opérateur ==: 3131 Les opérateurs de comparaison class Complexe{ friend operator==(Complexe const& a, Complexe const& b); private: double real; double img; public: Complexe(double, double); Complexe(); //… }; bool operator==(Complexe const& a, Complexe const& b) { return (a.real == b.real && a.img == b.img); }
  • 32. L'implémentation de l'opérateur== 2ème solution avec méthode d’instance On commence par créer une méthode publique estEgal() qui renvoie true si b est égal à l'objet dont on a appelé la méthode: bool Complexe::estEgal(Complexe const& b){ return (real == b.real && img == b. img); } Et on utilise cette méthode dans l'opérateur de comparaison : bool operator==(Complexe const& a, Complexe const& b) { return a.estEgal(b); } 3232 Les opérateurs de comparaison
  • 33. L'implémentation de l'opérateur== 2ème solution avec méthode d’instance À côté de la classe, vous rajoutez la définition de l’opérateur ==: 3333 Les opérateurs de comparaison class Complexe{ private: double real; double img; public: Complexe(double, double); Complexe(); bool estEgal(Complexe const&); //… }; bool operator==(Complexe const& a, Complexe const& b) { return a.estEgal(b); }
  • 34. L'implémentation de l'opérateur== Dans le main(), on peut faire un simple test de comparaison pour vérifier que l'on a fait les choses correctement : Output: Les nombres complexes sont identiques 3434 Les opérateurs de comparaison int main(){ Complexe z1(1.0, 2.0), z2(1.0, 2.0); if (z1 == z2) cout << "Les nombres complexes sont identiques"; else cout << "Les nombres complexes sont différents"; return 0; }
  • 35. Operateur != Pour tester si deux objets sont différents, il suffit de tester s'ils ne sont pas égaux! Voici la définition de la fonction operator==: bool operator!=(Complexe const& a, Complexe const& b) { if (a == b) //On utilise l'opérateur == qu'on a défini précédemment ! return false; //S'ils sont égaux, alors ils ne sont pas différents else return true; //Et s'ils ne sont pas égaux, c'est qu'ils sont différents } Ou en version courte bool operator!=(Complexe const& a, Complexe const& b) { return !(a==b); //On utilise l'opérateur == qu'on a défini précédemment ! } 3535 Les opérateurs de comparaison
  • 36. L'implémentation de l'opérateur!= Dans la définition de la classe, vous rajoutez le prototype de l’opérateur !=: 3636 Les opérateurs de comparaison class Complexe{ friend operator==(Complexe const& a, Complexe const& b); friend operator!= (Complexe const& a, Complexe const& b); private: double real; double img; public: //… }; bool operator==(Complexe const& a, Complexe const& b) { return (a.real == b.real && a.img == b. img); } bool operator!=(Complexe const& a, Complexe const& b) { return !(a==b); //On utilise l'opérateur == }
  • 37. L'implémentation de l'opérateur!= Dans le main(), on peut faire un simple test de comparaison: Output: Les nombres complexes sont identiques 3737 Les opérateurs de comparaison int main(){ Complexe z1(1.0, 2.0), z2(1.0, 2.0); if (z1 != z2) cout << "Les nombres complexes sont différents "; else cout << "Les nombres complexes sont identiques "; return 0; }
  • 38. Les autres opérateurs de comparaison Il nous reste encore quatre autres opérateurs de comparaison: <, >, <= et >=. Pour vous aider, je vous donne les prototypes: bool operator<(NomDeLaClasse const &a, NomDeLaClasse const& b); bool operator>(NomDeLaClasse const &a, NomDeLaClasse const& b); bool operator<=(NomDeLaClasse const &a, NomDeLaClasse const& b); bool operator>=(NomDeLaClasse const &a, NomDeLaClasse const& b); 3838 Les opérateurs de comparaison
  • 39. Pour surcharger un opérateur Op dans une classe NomDeLaClasse, il faut ajouter la méthode operatorOp dans la classe en question : class NomDeLaClasse{ ... // prototype de l’opérateur Op type_de_retour operatorOp(types_de_parametres); ... }; // définition de l’opérateur Op type_de_retour NomDeLaClasse::operatorOp(types_de_parametres) { ... } 3939 Surcharge interne
  • 40. 4040 Surcharge interne Exemple (1/3): class Complexe { friend ostream& operator<<(ostream& sortie, Complexe const& z); private: double real; double img; public: Complexe(double, double); Complexe(); void operator+=(Complexe const& z2); // z1 += z2; };
  • 41. 4141 Surcharge interne Exemple (2/3): Complexe::Complexe(double a, double b):real(a), img(b){} Complexe::Complexe(): Complexe(0.0, 0.0) {} void Complexe::operator+=(Complexe const& z2){ real += z2.real; img += z2.img; } ostream& operator<<(ostream& sortie, Complexe const& z) { sortie << "(" << z.real << ", " << z.img << ")"; return sortie; }
  • 42. 4242 Surcharge interne Exemple (3/3): int main(){ Complexe z1(1.5, 2.5), z2(1.3, 1.4); z1+=z2; cout << z1; return 0; } Output: (2.8, 3.9)
  • 43. 4343 Lien entre opérateurs L’on veut exprimer le lien sémantique des opérateurs + et += (dans les deux cas, la même opération somme) L’opérateur += est par nature un opérateur demandant moins de traitement car il ne créé pas de nouvel objet Complexe. Toujours, il vaut mieux de définir le plus lourd en fonction du plus léger.
  • 44. 4444 Lien entre opérateurs Exemple: const Complexe operator+(Complexe z1, Complexe const& z2){ z1+=z2; // utilise l'opérateur += redéfini précédemment return z1; } Le paramètre z1 étant passé par valeur, ici z1 est locale à la fonction.
  • 45. 4545 Lien entre opérateurs Exemple (1/3): class Complexe { friend ostream& operator<<(ostream& sortie, Complexe const& z); friend const Complexe operator+(Complexe z1, Complexe const& z2); private: double real; double img; public: Complexe(double, double); Complexe(); void operator+=(Complexe const& z2); // z1 += z2; };
  • 46. 4646 Lien entre opérateurs Exemple (2/3): Complexe::Complexe(double a, double b):real(a), img(b){} Complexe::Complexe(): Complexe(0.0, 0.0) {} void Complexe::operator+=(Complexe const& z2){ real += z2.real; img += z2.img; } const Complexe operator+(Complexe z1, Complexe const& z2){ z1 += z2; // utilise l'opérateur += redéfini précédemment return z1; } ostream& operator<<(ostream& sortie, Complexe const& z) { sortie << "(" << z.real << ", " << z.img << ")"; return sortie; }
  • 47. 4747 Lien entre opérateurs Exemple (3/3): int main(){ Complexe z1(1.5, 2.5), z2(1.3, 1.4), z3; z3=z1+z2; cout << z3; return 0; } Output: (2.8, 3.9)
  • 48. 4848 Surcharge interne ou Surcharge externe? Les opérateurs propres à une classe peuvent être surchargés en interne ou en externe : z3 = z1 + z2; SOIT z3 = z1.operator+(z2); SOIT z3 = operator+(z1, z2);
  • 49. 4949 Surcharge interne ou Surcharge externe? Surcharge interne: class Complexe { public: const Complexe operator+(Complexe const& z2) const; // .... }; const Complexe Complexe::operator+(Complexe const& z2) const{…} Surcharge externe: const Complexe operator+(Complexe z1, Complexe const& z2){…}; // ... class Complexe { friend const Complexe operator+(Complexe z1, Complexe const& z2); // ... };
  • 50. 5050 Préférez la surcharge externe chaque fois que vous pouvez le faire SANS friend c.-à-d. chaque fois que vous pouvez écrire l’opérateur à l’aide de l’interface de la classe (et sans copies inutiles). Préférez la surcharge interne si l’opérateur est « proche de la classe », c.-à-d. nécessite des accès internes ou des copies supplémentaires inutiles (typiquement operator+=). Surcharge interne ou Surcharge externe?
  • 51. 5151 Exemples: bool operator==(NomDeLaClasse const&) const; // ex: p == q bool operator<(NomDeLaClasse const&) const; // ex: p < q NomDeLaClasse& operator+=(NomDeLaClasse const&); // ex: p += q NomDeLaClasse& operator-=(NomDeLaClasse const&); // ex: p -= q NomDeLaClasse& operator*=(autre_type const); // ex: p *= x; NomDeLaClasse& operator++(); // ex: ++p NomDeLaClasse& operator++(int inutile); // ex: p++ const NomDeLaClasse operator-() const; // ex: r = -p; //Surcharges externes const NomDeLaClasse operator+(NomDeLaClasse, NomDeLaClasse const&); // r = p + q const NomDeLaClasse operator-(NomDeLaClasse, NomDeLaClasse const&); // r = p - q ostream& operator<<(ostream&, NomDeLaClasse const&); // ex: cout << p; const NomDeLaClasse operator*(autre_type, NomDeLaClasse const&); // ex: q = x * p; Surcharges de quelques opérateurs usuels
  • 52. 5252 const Complexe operator+(Complexe, Complexe const&); z3 = z1 + z2; ++(z1 + z2); // pas de sens z1 + z2 = f(x); // idem Pourquoi const en type de retour ?
  • 53. 5353 ostream& operator<<(ostream& sortie, Complexe const& z){ cout << z1 << endl; operator<<(cout << z1, endl); operator<<(operator<<(cout, z1), endl); Pourquoi operator<< retourne-t-il un ostream& ?
  • 54. 5454 z1 += z2; void Complexe::operator+=(Complexe const&); En C++, chaque expression fait quelque chose et vaut quelque chose : x = Expression; z3 = (z1 += z2); class Complexe { // ... Complexe& operator+=(Complexe const& z2); // ... }; Complexe& Complexe::operator+=(Complexe const& z2){ real += z2.real; img += z2.real; return *this; } this étant un pointeur sur un objet,*this est l'objet lui-même ! Notre opérateur renvoie donc l'objet lui-même. Quel type de retour pour operator+= ?
  • 55. 5555 Attention de ne pas utiliser la surcharge des opérateurs à mauvais escient et à veiller à les écrire avec un soin particulier. Les performances du programme peuvent en être gravement affectées par des opérateurs surchargés mal écrits. En effet, l’utilisation inconsidérée des opérateurs peut conduire à un grand nombre de copies d’objets : Utiliser des références dès que cela est approprié ! Avertissement
  • 56. 5656 Exemple: Comparez le code suivant qui fait de 1 à 3 copies inutiles : Complexe Complexe::operator+=(Complexe z2){ Complexe z3; real += z2.real; img += z2.img; z3 = *this; return z3; } Avec le code suivant qui n’en fait pas : Complexe& Complexe::operator+=(Complexe const& z2){ real += z2.real; img += z2.img; return *this; } Avertissement
  • 57. 5757 L’opérateur d’affectation = (utilisé par exemple dans a = b) : est le seul opérateur universel (il est fourni de toutes façons par défaut pour toute classe) est très lié au constructeur de copie, sauf que le premier s’appelle lors d’une affectation et le second lors d’une initialisation la version par défaut, qui fait une copie de surface, est suffisante dans la très grande majorité des cas si nécessaire, on peut supprimer l’opérateur d’affectation : class ClasseNonAffectation { // ... private: ClasseNonAffectation& operator=(ClasseNonAffectation const&) = delete; }; Opérateur d’affectation
  • 58. 5858 Remarque: Ne confondez pas le constructeur de copie avec la surcharge de l'opérateur d’affectation = (operator=). Ils se ressemblent beaucoup mais il y a une différence : le constructeur de copie est appelé lors de l'initialisation (à la création de l'objet) tandis que la méthode operator= est appelée si on essaie d'affecter un autre objet par la suite, après son initialisation. Exemple: Complexe z1 = z2; // constructeur de copie z1 = z2; // opérateur d’affectation: operator= Opérateur d’affectation
  • 59. 5959 L’opérateur d’affectation (méthode operator=) effectue le même travail que le constructeur de copie. Si l’on doit redéfinir l’opérateur d’affectation, son implémentation est donc relativement simple: NomDeLaClasse& NomDeLaClasse::operator=(NomDeLaClasse const& source) { if (this != &source) //On vérifie que l'objet n'est pas le même que celui reçu en argument { //On copie tous les champs … } return *this; //On renvoie l'objet lui-même } Surcharge de l’opérateur d’affectation
  • 60. 6060 Depuis C++11, pour implémenter l’opérateur d’affectation =, on choisit le schéma suivant : on commencera par définir une fonction swap() pour échanger 2 objets de la classe, (sûrement en utilisant celle de la bibliothèque utility (#include <utility>) sur les attributs) puis on définira l’opérateur d’affectation comme suit : NomDeLaClasse& NomDeLaClasse::operator=(NomDeLaClasse source) // Notez le passage par VALEUR { swap(*this, source); return *this; } Surcharge de l’opérateur d’affectation
  • 62. Références 62 1) http://www.cplusplus.com 2) https://isocpp.org/ 3) https://openclassrooms.com/fr/courses/1894236-programmez-avec-le-langage-c 4) https://www.tutorialspoint.com/cplusplus/ 5) https://en.cppreference.com 6) https://stackoverflow.com/ 7) https://cpp.developpez.com/ 8) Programmer en C++, Claude Delannoy, éditions Eyrolles, 2014. 9) Initiation à la programmation (en C++), Jean-Cédric Chappelier, & Jamila Sam, coursera, 2018. 10) Introduction à la programmation orientée objet (en C++), Jamila Sam & Jean- Cédric Chappelier, coursera, 2018. 62