OVH Cloud OVH Cloud

exemple de surcharge ?

4 réponses
Avatar
ByB
Bonjour,

Je cherche un exemple de surcharge de l'opérateur == en C++

Par exemple , si on a une classe :

class Cercle
{
int rayon;
int centreX;
int centreY;
};

et que l'on veut définir que deux objets Cercle sont égaux (==) ssi :

rayon1 == rayon2;
centreX1 == centreX2;
centreY1 == centreY2;


comment cela s'exprime t-il syntaxiquement sous la forme d'une
surcharge ?

Merci.



--
Lorsque votre ordinateur personnel est en panne, songez à vérifier la
qualité de l'interface fauteuil-clavier ! [Anonyme]

4 réponses

Avatar
Alexandre
bonjour,

Je cherche un exemple de surcharge de l'opérateur == en C++
class Cercle
{
int rayon;
int centreX;
int centreY;
};
et que l'on veut définir que deux objets Cercle sont égaux (==) ssi :
rayon1 == rayon2;
centreX1 == centreX2;
centreY1 == centreY2;
comment cela s'exprime t-il syntaxiquement sous la forme d'une surcharge ?


deux méthodes :
- soit l'opérateur == est une fonction membre de ta classe

class Cercle
{
public:
bool operator==(const Cercle& c)
{
return (rayon==c.rayon)&&(centreX==c.centreX)&&(centreY==c.centreY);
}
};

- soit l'opérateur == n'est pas membre, déclaré en dehors de ta classe
(utile uniquement si tu as besoin de conversions implicites, AMA ce n'est
pas ton cas ici. Attention, en cas d'opérateur externe, il faut soit qu'il
soit ami de la classe (pour pouvoir utiliser les membres privés) soit mieux,
qu'il utilise une fonction publique de la classe (par ex l'opérateur défini
ci dessus)

bool operator==(const Cercle& c1, const Cercle& c2)
{
return c1.operator==(c2);
}

Personnelement je préfère la version "membre", sauf dans le cas sus-cité des
convertions implicites...

Avatar
ByB
Alexandre vient de nous annoncer :
bonjour,

Je cherche un exemple de surcharge de l'opérateur == en C++
class Cercle
{
int rayon;
int centreX;
int centreY;
};
et que l'on veut définir que deux objets Cercle sont égaux (==) ssi :
rayon1 == rayon2;
centreX1 == centreX2;
centreY1 == centreY2;
comment cela s'exprime t-il syntaxiquement sous la forme d'une surcharge ?


deux méthodes :


Merci !


--
Nous vivons une société beaucoup trop permissive. Jamais encore la
pornographie ne s'était étalée avec une telle impudeur. Et en plus, les
films sont flous ! [Woody Allen]


Avatar
kanze
Alexandre wrote:

Je cherche un exemple de surcharge de l'opérateur == en C++
class Cercle
{
int rayon;
int centreX;
int centreY;
};
et que l'on veut définir que deux objets Cercle sont égaux (==) ssi :
rayon1 == rayon2;
centreX1 == centreX2;
centreY1 == centreY2;
comment cela s'exprime t-il syntaxiquement sous la forme d'une surcharg e ?


deux méthodes :
- soit l'opérateur == est une fonction membre de ta classe

class Cercle
{
public:
bool operator==(const Cercle& c)
{
return (rayon==c.rayon)&&(centreX==c.centreX)&&(centreY ==c.centreY);
}
};

- soit l'opérateur == n'est pas membre, déclaré en dehors de
ta classe (utile uniquement si tu as besoin de conversions
implicites, AMA ce n'est pas ton cas ici. Attention, en cas
d'opérateur externe, il faut soit qu'il soit ami de la classe
(pour pouvoir utiliser les membres privés) soit mieux, qu'il
utilise une fonction publique de la classe (par ex l'opérateur
défini ci dessus)

bool operator==(const Cercle& c1, const Cercle& c2)
{
return c1.operator==(c2);
}


Attention : tu ne peux pas avoir à la fois un membre et un
non-membre, comme tu a l'air de faire ici.

Ce que je fais en général, c'est de définir une fonction membre
isEqual(), puis de dériver d'une classe template :

template< typename T >
struct EqualityComparisonOps
{
friend bool operator==( T const& lhs, T const& rhs )
{
return lhs.isEqual( rhs ) ;
}

friend bool operator!=( T const& lhs, T const& rhs )
{
return ! lhs.isEqual( rhs ) ;
}
} ;

Donc :

class Cercle : private EqualityComparisonOps< Cercle >
{
public:
// ...
bool isEqual( Cercle const& other ) const ;
// ...
} ;

Du coup, j'ai systèmatiquement les deux opérateurs, en tant que
non-membres. En revanche, la définition de ce que signifie
l'équalité se trouve bien dans une fonction membre, comme il se
soid. Et en cas d'une évolution, je n'oublierais pas de mettre à
jour un, et non l'autre.

Personnelement je préfère la version "membre", sauf dans le
cas sus-cité des convertions implicites...


Je préfère l'orthogonalité. Dans la mesure où il faut parfois
les fonctions publiques, je préfère qu'elles soient
systèmatiquement publique. J'aime aussi l'idée de traiter les
deux opérands de façon orthogonale.

En gros, pour les opérateurs binaires : si les deux opérands
peuvent être des rvalues, j'utilise une fonction globale, si
l'opérateur de gauche doit être un lvalue, une fonction membre.
Et la plupart du temps (surtout s'il existe plusieurs opérateurs
avec un rapport entre eux, comme == et !=), j'implémente une
fonction membre avec un nom que l'opérateur appelle, comme ici.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Alexandre
Attention : tu ne peux pas avoir à la fois un membre et un
non-membre, comme tu a l'air de faire ici.


oui, c'était juste pour éviter de retaper toute une fonction ;-)


Ce que je fais en général, c'est de définir une fonction membre
isEqual(), puis de dériver d'une classe template :


<...>

Du coup, j'ai systèmatiquement les deux opérateurs, en tant que
non-membres. En revanche, la définition de ce que signifie
l'équalité se trouve bien dans une fonction membre, comme il se
soid. Et en cas d'une évolution, je n'oublierais pas de mettre à
jour un, et non l'autre.


tout à fait. La solution de dériver d'un template de comparaison est sympa.