22
Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Thierry EUDE Module 5 : La surcharge des opérateurs Département d’informatique et de génie logiciel

Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Embed Size (px)

Citation preview

Page 1: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Programme de baccalauréat en informatique Programmation Orientée Objets

IFT-19946

Thierry EUDEThierry EUDE

Module 5 : La surcharge des opérateurs

Département d’informatique et de génie logiciel

Page 2: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

2

Définition

Consiste à redéfinir des opérateurs usuels comme +, -, *, /, =, <, [], etc...

sur de nouveaux types : les classes.

Particulièrement intéressante avec - les nombres complexes, les fractions, les vecteurs, les matrices, les

chaînes de caractères...

Dans certaines situations, rend la lecture du code plus facile :d = d1.plus(d2) --> d = d1 + d2

Page 3: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

3

Listes des opérateurs permis

Liste complète des opérateurs qui peuvent être surchargés :

+ - * / % ^ & | ~ !

= < > += -= *= /= %= ^= &=

|= << >> <<= >>= == != <= >= &&

|| ++ -- -> ->* [] () ,

Page 4: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

4

Ce qui n'est pas permis

On ne peut pas surcharger les opérateurs : . .* :: ?:

On ne peut pas créer de nouveaux opérateurs :|x| i.e. valeur absoluey := x i.e. assignation à la Pascaly = x**2 i.e. x à la puissance 2.

Page 5: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

5

Définir un opérateur surchargé

En C++, mot-clé operator suivi de l'opérateur.Les règles de préséance et d'associativité sont les mêmes

que les opérateurs usuels. • respecter ces règles pour ne pas avoir des résultats allant contre l'intuition.

Il faut éviter les surprises et la confusion. • Le langage ne renforce pas la signification d'un opérateur donné.

il est possible de définir l'opérateur + qui réalise une soustraction... À éviter!

Page 6: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

6

Exemples

class Date{public: bool operator== (const Date& obj) const; bool operator< (const Date& obj) const; friend std::ostream& operator<<(std::ostream& os, const Date& obj);private: long m_temps;};bool Date::operator==(const Date& obj) const{ return m_temps == obj.m_temps;}bool Date::operator<(const Date& obj) const{ return m_temps < obj.m_temps;}

Page 7: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

7

Exemples

std::ostream& operator<<(std::ostream& os, const Date& obj){ os << obj.m_temps; return os;}

// --- Exemple d'utilisationvoid main(){ Date d1; Date d2(4,11,2001); bool bEgal = (d1 == d2); //--- d1.operator==(d2) bool bInferieur = (d1 < d2); //--- d1.operator<(d2) cout << d1 << endl; //--- operator<<(cout, d1) cout << d2 << endl; //--- operator<<(cout, d2)}

Page 8: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

8

Opérateurs complémentaires

Le langage C++ ne rend pas équivalent les opérateurs v += w et v = v + w.

• Il faut définir les opérateurs +=, = et +.

x++ pas nécessairement égal à x = x + 1

La règle : •définir un ensemble complet d'opérateurs qui ont des interactions

naturelles entre eux :a = a + b --> a += b.

Page 9: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

9

Conversion de type

Conversion d'un objet d'un type en un autre type :• possible avec la surcharge des opérateurs.

Exemple : Soit une string,• il peut être intéressant de définir une conversion en const char* pour passer facilement en argument de beaucoup de librairies.

Il s'agit ici de déterminer ce qui est préférable :conversion implicite ou conversion explicite?

Page 10: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

10

Exemple

class string{public: operator const char* () const;

const char* c_str () const;private: char* m_strP;};// --- Conversion implicitestring::operator const char*() const{ return m_strP;}// --- Conversion expliciteconst char* string::c_str() const{ return m_strP;}

Page 11: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

11

Exemple

// --- fopen (const char* fP) est une fonction du // --- C standard qui permet d'ouvrir un fichier.void main(){ string nomFichier("fichier.txt");

// --- Conversion implicite, i.e. appel // --- de l'opérateur de conversion en const char* FILE *file1P = fopen(nomFichier);

// --- Conversion explicite, i.e. appel // --- explicite de la méthode string::c_str(). FILE *file2P = fopen(nomFichier.c_str());}

Il faut éviter les conversions implicites :On ne contrôle pas ce qui ce passe et on risque d'avoir des surprises et des imprévus...

Page 12: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

12

Conversion avec un constructeur

Il est possible de convertir un type vers un autre en passant par un constructeur.

Exemple : • un char* peut être convertis en string parce que la string a défini

un constructeur avec un const char* : string (const char* strP);

conversion implicite.

• La string pourrait avoir un constructeur acceptant un double. - Pour contrôler quand cette conversion se fera :ajouter le mot-clé explicit devant le constructeur : explicit string (double d);conversion explicite.

Page 13: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

13

Exemple

class string{public: string(const char* strP); explicit string(double d);private: char* m_strP;};string::string(const char* strP){ PRECONDITION (strP != 0); m_strP = new char[strlen(strP)+1]; strcpy(m_strP, strP);}string::string(double d){ ostringstream os; os << d; *this = os.str();}

Page 14: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

14

Exemple

void foo (string str);void main(){ double d = 2.2;

// --- Conversion implicite par le constructeur foo ("Bonjour la police");

// Error : no implicit conversion from double to string foo (d);

// --- Ok: appel explicite pour la conversion foo (string(d));}

Page 15: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

15

Opérateur []

Permet d'obtenir un comportement vectoriel pour des classes dont le concept correspond.

Exemple :string

il faut vérifier en précondition la validité de l'indice demandé.

Page 16: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

16

Exemple

class string{ char& operator[](int pos); const char& operator[](int pos) const;};char& string::operator[](int pos){ PRECONDITION(pos >= 0 && pos < size()); return m_strP[pos];}const char& string::operator[](int pos) const{ PRECONDITION(pos >= 0 && pos < size()); return m_strP[pos];}

Version en modification

Version en consultation

Page 17: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

17

Exemple

// --- Utilisation de l'opérateur []void main(){ string str("toto"); // --- Appel en consultation cout << str[3]; // --- imprime 'o' // --- Appel en modification str[0] = 'm'; // --- str devient "moto"}

Page 18: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

18

Opérateur ()

Peut servir par exemple pour accéder une matrice à 2 dimensions.

class Matrice2D{public: Matrice2D(int r, int c); double operator() (int r, int c) const;private: vector<double> m_matrice; int m_nbRangee; int m_nbColonne;};

Page 19: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

19

Exemple

double Matrice2D::operator()(int r, int c) const{ PRECONDITION(r > 0 && r <= m_nbRangee); PRECONDITION(c > 0 && c <= m_nbColonne); return m_matrice[(r-1)*m_nbColonne + c];}

void main(){ Matrice2D m(5,5); ... // On met des données dans la matrice

// --- On accède à l'élément de la 3e rangée // --- et de la 4e colonne. double x = m(3, 4);}

Page 20: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

20

Conversion en valeur de vérité

Conversion pour l'état d'un objet : la conversion en void*.

Exemple, la classe std::istream définit la conversion en void*.

Intérêt : ce type de pointeur ne peut être utilisé que dans un test logique ou une

assignation. Cela fournit une manière intéressante d'interroger l'état d'un objet.

La librairie des iostream du standard utilise largement ce type de conversion.

Page 21: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

21Exemple

<istream> …template<class E, class T = char_traits<E> > class basic_istream;typedef basic_istream<char, char_traits<char> > istream; …basic_istream An object of class basic_istream<E, T> stores:A virtual public base object of class basic_ios<E, T>.

basic_ios::operator void *operator void *() const; The operator returns a null pointer only if fail().

void main(){ int x; cin >> x; if (cin) // --- appel de l'opérateur de conversion { // --- pas d'erreur, continuer le traitement } }

Page 22: Programme de baccalauréat en informatique Programmation Orientée Objets IFT-19946 Thierry EUDE Module 5 : La surcharge des opérateurs Département dinformatique

Département d’informatique et de génie logiciel

22

Synthèse

Surcharge d’opérateur• • • • constructeur• []• () • vérité