Exercice – Apprivoiser la surcharge d'opérateurs
Quelques exercices pour apprivoiser la
surcharge d'opérateurs
avec
C#.
Activité – Classe TiTableau
Nous allons coder une classe TiTableau, qui
modélisera... un petit tableau unidimensionnel d'entiers de taille fixée à la construction.
Cette classe offrira une gamme de services de base, soit :
- Une propriété privée Substrat qui donnera accès au tableau de int
encapsulé
dans un TiTableau
- Un constructeur paramétrique public acceptant en paramètre la taille du
TiTableau (exprimée en nombre d'éléments) de même qu'une valeur initiale, et qui
(a) instanciera le tableau de int
sous-jacent (le Substrat) et (b) le remplira
avec la valeur initiale passée en paramètre
- Un constructeur paramétrique public acceptant en paramètre la taille du
TiTableau (exprimée en nombre d'éléments), et qui (a) instanciera le tableau de int
sous-jacent (le Substrat) et (b) le remplira
avec des zéros
- Une méthode publique Contient acceptant en paramètre une valeur entière, et
retournant true seulement si cette valeur est dans le TiTableau
- Une propriété publique Taille permettant de
consulter le nombre d'éléments du tableau, mais ne permettant pas de le changer
- Une propriété publique EstVide qui sera vraie
seulement si le nombre d'éléments du tableau est zéro
- Une méthode ToString, spécialisation de la
méthode
de la classe object, qui retournera une chaîne
comprenant les entiers dans le TiTableau et séparés
les uns des autres par un espace (conséquemment, si le
TiTableau nommé tt contient les entiers
1, 2 et 3 dans
l'ordre, alors tt.ToString() donnera la chaîne
"1 2 3" (notez qu'il n'y a pas d'espace au début et à la fin de cette
chaîne)
Nous allons
aussi implémenter quelques opérateurs pour cette classe, soit :
- Les opérateurs relationnels (==, !=, <, <=, >, >=). Notez que Les opérateurs relationnels d'ordonnancement implémenteront un
ordonnancement lexicographique
(grosso modo : l'ordre du dictionnaire, mais avec des séquences d'entiers au
lieu de séquences de caractères)
- Profitez-en pour vous assurer que TiTableau
implémente les interfaces
IEquatable<TiTableau> et
IComparable<TiTableau>!
- Un opérateur + binaire (deux opérandes)
capable d'additionner un à un les éléments de deux
TiTableau de même Taille, tel que (1 2 3)+(1 2 4)
vaudra (2 4 7)
- Un opérateur - unaire (une opérande) tel que -(1 2 3)
vaudra (-1 -2 -3)
- Un indexeur (version
C# de l'opérateur [] sous forme de propriété)
offrant à la fois un accesseur (get) et un
mutateur (set) pour que le TiTableau
se comporte un peu comme un tableau
Un programme de test possible serait :
TiTableau tt0 = new (5);
for (int i = 0; i != tt0.Taille; ++i)
tt0[i] = i + 1;
Console.WriteLine($"tt0 : {tt0}");
TiTableau tt1 = new (5);
for (int i = 0; i != tt1.Taille; ++i)
tt1[i] = i + 1;
Console.WriteLine($"tt1 : {tt1}");
TestRelationnels(tt0, tt1);
Console.WriteLine($"{tt0} + {tt1} == {tt0 + tt1}");
TestRelationnels(tt0, tt0 + tt1);
Console.WriteLine($"-({tt0}) == {-tt0}");
TestRelationnels(tt0, -tt0);
static void TestRelationnels(TiTableau tt0, TiTableau tt1)
{
if (tt0 == tt1)
Console.WriteLine($"{tt0} == {tt1}");
if (tt0 != tt1)
Console.WriteLine($"{tt0} != {tt1}");
if (tt0 < tt1)
Console.WriteLine($"{tt0} < {tt1}");
if (tt0 <= tt1)
Console.WriteLine($"{tt0} <= {tt1}");
if (tt0 > tt1)
Console.WriteLine($"{tt0} > {tt1}");
if (tt0 >= tt1)
Console.WriteLine($"{tt0} >= {tt1}");
}
... ce qui devrait afficher :
tt0 : 1 2 3 4 5
tt1 : 1 2 3 4 5
1 2 3 4 5 == 1 2 3 4 5
1 2 3 4 5 <= 1 2 3 4 5
1 2 3 4 5 >= 1 2 3 4 5
1 2 3 4 5 + 1 2 3 4 5 == 2 4 6 8 10
1 2 3 4 5 != 2 4 6 8 10
1 2 3 4 5 < 2 4 6 8 10
1 2 3 4 5 <= 2 4 6 8 10
-(1 2 3 4 5) == -1 -2 -3 -4 -5
1 2 3 4 5 != -1 -2 -3 -4 -5
1 2 3 4 5 > -1 -2 -3 -4 -5
1 2 3 4 5 >= -1 -2 -3 -4 -5
Exercice – Classe Point
À titre d'exercice, vous allez coder une classe Point
modélisant un point 2D. Cette classe
implémentera IEquatable<Point> et offrira les services suivants :
- Des propriétés publiques entières immuables X et
Y
- Un opérateur == et un opérateur
!= pour comparer deux instances de Point
- Un opérateur + binaire tel que
(X0,Y0) + (X1,Y1) donnera (X0+X1,Y0+Y1)
- Un opérateur - unaire tel que
-(X,Y) donnera (-X,-Y)
- Un constructeur par défaut, modélisant un Point
à l'origine
- Un constructeur paramétrique, modélisant un Point
à une position (X,Y) choisie par le code
client
- Une méthode Distance pour évaluer la distance
entre deux points (vous pouvez l'offrir sous forme de méthode d'instance ou
sous forme de méthode de classe, au choix). Rappel : la formule pour évaluer la distance entre deux
points et est
Écrivez un programme de test pour valider votre oeuvre.
Exercice – Classe Naturel
À titre d'exercice, vous allez coder une classe Naturel
modélisant entier naturel, donc un entier dont la valeur est supérieure ou égale à
zéro. Cette classe implémentera IEquatable<Naturel>
et IComparable<Naturel>. De plus, elle offrira les services suivants :
- Les opérateurs arithmétiques usuels (+ et
- unaires – est-ce une bonne idée selon vous? – de même que +, -,
*, / et %
binaires)
- Les opérateurs relationnels (<,
<=, >, >=,
== et !=)
- Les opérateurs ++ et --
- Un constructeur par défaut, modélisant un Naturel
de valeur 0
- Un constructeur paramétrique, modélisant un Naturel
de valeur choisie par le code
client
Écrivez un programme de test pour valider votre oeuvre. Toute tentative de
placer un Naturel dans un état incorrect devrait
lever ErreurDomaineException.