1242.2 Langage C++ - 2025-2026
1. Introduction
2. Surcharges des opérateurs
3. Surcharge de
4. Surcharge de
5. Autres surcharges (
6. Bonnes pratiques
Comment les additionner ?
ou
Permet de redéfinir le comportement des opérateurs
Pour manipuler les objets comme des types simples
Complex c1(2,3), c2(1,1), c3;
c3 = c1 + c2;
c1.show();
On ne peut pas redéfinir les opérateurs sur les types primitifs
Seulement pour les classes/struct définies par nous
Seuls les opérateurs existants peuvent être surchargés
✅ Conserver la sémantique initiale de l'opérateur
= + - * / ^ %
== += -= *= /= ^= %=
< <= > >= << >> <<=
>>= ++ -- & | ! &=
|= != , [] () && ||
~ xor xor_eq and and_eq or or_eq
not not_eq bitand bitor compl
-> ->* new new[] delete delete[]
. .* :: ?: sizeof
Pour chaque opérateur ♦, il existe une méthode
// Complex.h
class Complex
{
public:
// ⚠️ this and argument are const
Complex operator+(const Complex &) const;
private:
double m_real{0};
double m_imag{0};
};
// Complex.cpp
Complex Complex::operator+(const Complex &c) const
{
return Complex(r + c.r, i + c.i);
}
Complex c1, c2, c;
int x, y;
...
c = c1 + c2; // ✅ c = c1.operator+(c2);
// ✅ if conversion exists
c = c1 + y; // ✅ c = c1.operator+(Complex(y));
// ⛔ x.operator+(c2) does not compile
c = x + c2; // ⛔ x is not a Complex
// ⚠️ Needs accessors
Complex operator+(const Complex &x, const Complex &y)
{
return Complex(x.getR() + y.getR(), x.getI() + y.getI() );
}
// Complex.h
friend Complex operator+(const Complex&, const Complex&);
// Complex.cpp
Complex operator+(const Complex &x, const Complex &y)
{
return Complex(x.r + y.r, x.i + y.i );
}
Complex c1, c2, c;
int x, y;
...
c = c1 + c2; // ✅ c = operator+(c1, c2);
// ✅ if conversion exists
c = c1 + y; // ✅ c = operator+(c1, Complex(y));
// ✅ if conversion exists
c = x + c2; // ✅ c = operator+(Complex(x), c2);
Les opérateurs
std::ostream& operator<<(std::ostream &s, const Point &p)
{
return s << '(' << p.m_x << ',' << p.m_y << ')';
}
L'opérande de gauche est une référence sur le flux
Cette fonction ne peut pas être membre de la classe
Le renvoi d'une référence permet de l'utiliser comme
On pourra donc faire des appels en cascade :
std::cout << p1 << p2 << '\n';
operator<<(operator<<(operator<<(std::cout, p1), p2), '\n');
|----------------------| ostream&
|---------------------------------------| ostream&
|-------------------------------------------------------| ostream&
Exemple d'utilisation d'
int main()
{
Point p;
std::print("Enter a point (x,y): ");
std::cin >> p;
std::cout << "Point entered: " << p << '\n';
return 0;
}
On veut que l'utilisateur respecte un format prédéfini :
Enter a point (x,y): ( 2 , 3 )
Point entered: (2,3)
std::istream& operator>>(std::istream &in, Point &p)
{
char c;
in >> c;
if (c == '(')
{
in >> p.m_x >> c;
if (c == ',')
{
in >> p.m_y >> c;
if (c == ')')
return in;
}
}
in.setstate(std::ios::failbit);
return in;
}
L'affectation est une opération prédéfinie
Doit parfois être redéfini pour des copies en profondeur
⚠️ Affectation vs construction par copie
int main()
{
NamedPoint pt(1, 4, "P1"), copyPt;
// ⚠️ Copy constructor
NamedPoint copyPt2 = pt;
// ⚠️ Assignment
copyPt = pt;
return 0;
}
class NamedPoint
{
public:
NamedPoint(int = 0, int = 0, const char* = "?");
NamedPoint(const NamedPoint &);
virtual ~NamedPoint();
NamedPoint& operator=(const NamedPoint &);
private:
int m_x{0};
int m_y{0};
char* m_name{nullptr};
};
// ✅ Return reference to allow chaining
NamedPoint& NamedPoint::operator=(const NamedPoint &p)
{
// ✅ Avoid self-assignment
if (this == &p)
{
return *this;
}
m_x = p.m_x;
m_y = p.m_y;
delete[] m_name;
m_name = nullptr;
m_name = new char[strlen(p.m_name) + 1];
strcpy_s(m_name, strlen(p.m_name) + 1, p.m_name);
return *this;
}
Les opérateurs de conversion
class Point
{
public:
// Conversion int → Point
Point(int a) : m_x(a), m_y(0) {}
// Conversion Point → int: Manhattan distance
operator int() const
{
return std::abs(m_x) + std::abs(m_y);
}
private:
int m_x{0};
int m_y{0};
};
Les opérateurs d'incrémentation et de décrémentation
class Counter
{
public:
Counter(int x);
// PRE - Returns reference: no copy, usable as lvalue
Counter& operator++()
{
++m_x;
return *this;
}
// POST - Standard C++: use int parameter to distinguish from pre
Counter operator++(int)
{
Counter temp(*this);
++m_x;
return temp;
}
private:
int m_x{0};
};
Les foncteurs —
Un objet appelable comme une fonction, mais qui porte son propre état
class Linear
{
public:
Linear(double a, double b) : m_a(a), m_b(b) {}
double operator()(double x) const
{
return m_a * x + m_b;
}
private:
double m_a{0};
double m_b{0};
};
Linear f(2, 1); // f(x) = 2x + 1
Linear g(-1, 0); // g(x) = -x
std::println("f(4) = {}", f(4)); // 9
std::println("g(7) = {}", g(7)); // -7
✅
✅
✅
✅
✅ les opérateurs arithmétiques (recommandé)
✅ les opérateurs de comparaison (recommandé)