OVH Cloud OVH Cloud

operator

7 réponses
Avatar
Simon L
Bien, voici mon probleme. J'ai fait une classe qui marche très bien sauf
quand je veux faire la comparaison < . Mon compilateur me donne ceci
comme erreur (que je ne comprends pas):

-----
main.cpp:18: error: passing 'const Fraction' as 'this' argument of 'bool
Fraction::operator<(const Fraction&)' discards qualifiers
-----

Voici une partie du code dans le .h

-----
class Fraction
{
private:
int num, denum; // Le numerateur et denominateur

...
public:
...
bool operator==(const Fraction&);
bool operator<(const Fraction&);
...

};
-----

Et voici la partie du code dans le .cpp

-----
bool Fraction::operator<(const Fraction& _src)
{
double Premier;
double Deuxieme;

Premier = num/denum;
Deuxieme = _src.num/_src.denum;

return (Premier < Deuxieme);
}
-----


J'allais oublier le code dans le main.cpp

-----
template <class T>
T ElementMediant(const T& A, const T& B, const T& C)
{
bool tmp[3];

tmp[0] = (A<B);
tmp[1] = (A<C);
tmp[2] = (B<C);
...
}
-----

Si quelcun pourrait m'aider, ce serait très apprécié étant donné que ca
fait une heure que je me pete la tete contre le mur.

PS: le == marche et le template marche avec des int

Merci

7 réponses

Avatar
Loïc Joly
Simon L wrote:

Bien, voici mon probleme. J'ai fait une classe qui marche très bien sauf
quand je veux faire la comparaison < . Mon compilateur me donne ceci
comme erreur (que je ne comprends pas):


Tu as oublié de déclarer constant ton opérateur <.

De plus, cet opérateur, il vaux mieux en général le mettre en dehors de
la classe.

--
Loïc

Avatar
Simon L
Loïc Joly wrote:

Simon L wrote:

Bien, voici mon probleme. J'ai fait une classe qui marche très bien
sauf quand je veux faire la comparaison < . Mon compilateur me donne
ceci comme erreur (que je ne comprends pas):



Tu as oublié de déclarer constant ton opérateur <.

De plus, cet opérateur, il vaux mieux en général le mettre en dehors de
la classe.



Je l'ai mise à l'extérieur de la classe et ca marche bien maintenant :)
merci bcp


Avatar
Michael
De plus, cet opérateur, il vaux mieux en général le mettre en dehors
de la classe.



Pourquoi ça?

J'ai toujours déclaré mes operator< dans mes classes, et ça a toujours très
bien marché pour moi???

Avatar
Loïc Joly
Michael wrote:

De plus, cet opérateur, il vaux mieux en général le mettre en dehors
de la classe.




Pourquoi ça?

J'ai toujours déclaré mes operator< dans mes classes, et ça a toujours très
bien marché pour moi???


Par symétrie. S'il est possible par exemple de convertir d'un entier
vers ta classe, avec un opérateur à l'intérieur de la classe, le code
suivant est valide :

maClasse < 42;

Mais pas celui ci, ce qui est surprenant :

42 < maClasse;

Idem pour d'autres opérateurs (+, -, *, /, ==, ...)

--
Loïc


Avatar
kanze
Michael wrote:
De plus, cet opérateur, il vaux mieux en général le mettre
en dehors de la classe.


Pourquoi ça?

J'ai toujours déclaré mes operator< dans mes classes, et ça a
toujours très bien marché pour moi???


Moi aussi:-).

La raison pourquoi on préfère parfois les déclarer en dehors de
la classe, c'est parce que les conversions implicites ne
s'appliquent pas sur le this d'une fonction membre. Donc, si tu
as des conversions implicites vers la classe, il vaut mieux une
fonction non-membre.

Mais c'est un grand si. Si des conversions implicites sont
pratiquement la norme pour des types numériques (et avoue-le, ça
serait un peu bête si x > 0 était légal, mais 0 < x non), et
d'un itérateur vers un itérateur const, elles ne sont pas si
fréquentes autrement.

--
James Kanze GABI Software http://www.gabi-soft.fr
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
Falk Tannhäuser
Simon L wrote:
class Fraction
{
private:
int num, denum; // Le numerateur et denominateur
...
public:
...
bool operator==(const Fraction&);
bool operator<(const Fraction&);
...
};
[...]

bool Fraction::operator<(const Fraction& _src)
{
double Premier;
double Deuxieme;

Premier = num/denum;
Deuxieme = _src.num/_src.denum;

return (Premier < Deuxieme);
}


En plus des remarques de Loïc :

Vu que 'num' et 'demum' sont du type 'int',
l'expression 'num/denum' donnera un 'int',
même si elle est affectée à un 'double' !
Ainsi, avec
Fraction a(1, 9);
Fraction b(1, 2);
en appelant 'a < b', 'Premier' vaudra 1/9 == 0
(converti en 0.0 à l'affectation) et 'Deuxieme'
vaut 1/2 == 0 (0.0) aussi. Par conséquent,
'a < b' donne 'false' ce qui est faux.

1ère tentative de solution :
bool operator<(Fraction const& a, Fraction const& b)
{
return double(a.num)/a.denum < double(b.num)/b.denum;
}

Je ne suis cependant pas sûr qu'un calcul utilisant des
flottants donne ici toujours un résultat correct ...

2ème proposition :

inline int sign(int i) { return i>0 ? 1 : (i<0 ? -1 : 0); }

bool operator<(Fraction const& a, Fraction const& b)
{
return a.num * abs(b.denum) * sign(a.denum) <
b.num * abs(a.denum) * sign(b.denum);
}

Par contre, il faudra faire gaffe aux débordements lors de
la multiplication - éventuellement faire les calculs en
'long long'.

Falk

Avatar
Jean-Sebastien Mouret
Simon L writes:

Loïc Joly wrote:

Simon L wrote:

Bien, voici mon probleme. J'ai fait une classe qui marche très bien
sauf quand je veux faire la comparaison < . Mon compilateur me
donne ceci comme erreur (que je ne comprends pas):
Tu as oublié de déclarer constant ton opérateur <.

De plus, cet opérateur, il vaux mieux en général le mettre en dehors
de la classe.



Je l'ai mise à l'extérieur de la classe et ca marche bien maintenant :)
merci bcp


http://www.boost.org/libs/utility/operators.htm


--
js