View
105
Download
0
Category
Preview:
Citation preview
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
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
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 :
+ - * / % ^ & | ~ !
= < > += -= *= /= %= ^= &=
|= << >> <<= >>= == != <= >= &&
|| ++ -- -> ->* [] () ,
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.
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!
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;}
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)}
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.
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?
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;}
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...
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.
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();}
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));}
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é.
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
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"}
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;};
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);}
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.
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 } }
Département d’informatique et de génie logiciel
22
Synthèse
Surcharge d’opérateur• • • • constructeur• []• () • vérité
Recommended