Surcharge d’opérateur
Surcharge d’opérateur
- C++ permet de surdéfinir les opérateurs tels que
+
,=
,+=
,++
,<<
,new
… - Fondamentalement, l’appel à un opérateur est identique à l’appel d’une fonction → possibilité de surdéfinir
- Le but est de définir ces “fonctions” pour des classes dépourvues de ces opérateurs
Exemple de surcharge de l’opérateur unaire +=
Objectif : réaliser ce type d’opération logique
int main() { point my_point1(2, 3); point my_point2(4, 5); my_point1 += my_point2; }
Exemple de surcharge de l’opérateur unaire +=
// Déclaration class point { public: point(); point(const double x_, const double y_); double x() const; double y() const; private: double m_x; double m_y; };
Exemple de surcharge de l’opérateur unaire +=
// Déclaration class point { public: point(); point(const double x_, const double y_); double x() const; double y() const; point & operator+=(const point & point_); private: double m_x; double m_y; };
Exemple de surcharge de l’opérateur unaire +=
// Définition point & point::operator+=(const point & point_) { m_x += point_.x(); m_y += point_.y(); return *this; }
→ utilisation du pointeur this
qui retourne l'adresse de l'objet
courant
Exemple de surcharge de l’opérateur unaire +=
// Définition point & point::operator+=(const point & point_) { m_x += point_.x(); m_y += point_.y(); return *this; } ... // Utilisation int main() { point my_point1(2, 3); point my_point2(4, 5); my_point1 += my_point2; }
→ équivalent à l'usage d'une méthode ajoute
s'utilisant de la façon
suivante my_point1.ajoute(my_point2);
Exemple de surcharge de l’opérateur binaire +
int main() { point my_point1(2, 3); point my_point2(4, 5); point my_point3 = my_point1 + my_point2; }
// Déclaration class point { ... }; point operator+(const point & point1_, const point & point2_); // Définition point operator+(const point & point1_, const point & point2_) { return point(point1_.x() + point2_.x(), point1_.y() + point2_.y()); }
Opérateur d’affectation =
L’opérateur d’affectation
=
permet d’affecter une nouvelle valeur à un objet déjà existantint main() { point my_point1(2, 3); point my_point2(3, 4); my_point2 = my_point1; }
Sa surcharge se fait comme pour n’importe quel opérateur
// Déclaration class point { point & operator=(const point & point_); };
Opérateur d’affectation =
Rien n’empêche toutefois d’affecter un objet à lui-même
point my_point; my_point = my_point;
Lorsque cette “affectation” risque de corrompre l’objet, utiliser un garde-fou :
// Définition point & point::operator=(const point & point_) { if (&point_ != this) { // garde-fou m_x = point_.x(); m_y = point_.y(); } return *this; }
Constructeur de recopie et opérateur d’affectation =
Le constructeur de recopie est la méthode appelée lors de la copie d’un objet vers un autre objet du même type
int main() { point my_point1(2, 3); point my_point2 = my_point1; }
class point { point(const point & point_); }; point::point(const point & point_) { m_x = point_.x(); m_y = point_.y(); }
Constructeur de recopie et opérateur d’affectation =
- C++ fournit par défaut le constructeur de recopie et l’opérateur
d’affectation
=
- Lorsque ces versions triviales ne suffisent pas (cas de l'allocation
dynamique) il faut choisir entre deux solutions :
- Écrire une version correcte,
Rendre impossible la copie et l’affectation, en déclarant ces méthodes privées, sans les définir :
class pas_de_copie { private: pas_de_copie(const pas_de_copie&); pas_de_copie & operator=(const pas_de_copie&); };
Annexes
Fonctions et classes amies
- Du fait du principe d’encapsulation des données, les fonctions extérieures à la classe n’ont pas accès aux membres privées de cette classe…
- … à l’exception des fonctions amies
- Utilité : quasi nulle sauf pour quelques opérations (dont la surcharge d’opérateur)
Exemple de fonction amie d’une classe
// Déclaration avec friend class particule { friend void stupid_thing(particule & particule_); ... }; ... // Définition void stupid_thing(particule & particule_) { particule_.m_mass = 0.511; } ... // Utilisation int main() { particule my_muon(105.6, -1.6e-19); stupid_thing(my_muon); // muon $\equiv$ électron ?? wtf !! }
Classe amie d’une autre classe
Méthode d’une classe
B
, amie d’une autre classeA
class A { ... friend void B::methode_de_B(A & A_); ... };
Classe
B
amie d’une autre classeA
class A { ... friend class B; ... };