Surcharge d'opérateur sur des structures

Surcharge d'opérateur sur des structures - C++ - Programmation

Marsh Posté le 15-07-2007 à 20:41:47    

Salut,
 
est-il possible de surcharger un opérateur non pas dans une classe, mais dans une struct ?
 
J'ai une structure du type :
 

Code :
  1. struct Structure
  2. {
  3. ClasseA variable1;
  4. };
  5. Structure struct1;
  6. Structure struct2;


 
Si je fais :
 

Code :
  1. struct2 = struct1;


 
J'ai une erreur :
 

Code :
  1. Ambiguity between ClasseA::operator =(ClasseA) and ClasseA::operator=(const ClasseA & )


 
Cependant, je n'ai pas ce problème lorsque j'appelle explicitement :
 

Code :
  1. ClasseA objet1;
  2. ClasseA objet2;
  3. objet1 = objet2;

;
 
Le problème semble définitivement lié à l'encapsulation dans une struct.
 
J'espère que vous pourrez m'aider  :jap:

Reply

Marsh Posté le 15-07-2007 à 20:41:47   

Reply

Marsh Posté le 15-07-2007 à 20:53:40    

comment il est défini ton operator = de ClasseA ?

Reply

Marsh Posté le 15-07-2007 à 20:59:50    

Code :
  1. template <class type> void
  2. Coord_2D<type>::operator =(type value)
  3. {
  4.  x=value;
  5.  y=value;
  6. }


Message édité par Vel-Ryphon le 15-07-2007 à 21:00:02
Reply

Marsh Posté le 15-07-2007 à 22:28:02    

Code :
  1. Coord_2D<type> & Coord_2D<type>::operator = ( const type &value )
  2. {
  3.      if( this != &value )
  4.      {
  5.         x=value;
  6.         y=value;
  7.      }
  8.      return *this;
  9. }


 

 
const type &value, sinon ça fait théoriquement une copie (par constructeur de recopie)
 
pas void et return *this, parce que sinon tu peux pas écrire a=b=c;
 
sur des types complexes, tester si this != &value pour éviter de détuire l'object par auto-digestion sans apéro. (pour du float/int ça devrait passer) là je te l'ai mis pour le principe

 
edit: pardon, j'avais pas vu que tu voulais initialiser les deux coordonnées et non définir l'opérateur d'assignement objet à objet
 
si tu définis un operator = ( quelquonque ), il faut ptet obligatoirement définir un opérateur d'assignement.
mais quand même Coord_2D<type> & Coord_2D<type>:: operator = ( const type &value )  
(ou const type value )
 
---
 
pour lever l'ambiguité, ptet ne pas faire d'opérateur = ( const type value ), mais un constructeur explicite ( const type value ), et laisser le compilo optimiser l'assignement/construction dans le cas des " variable1=2 ";
ça évitera les collisions avec l'assignement.


Message édité par bjone le 15-07-2007 à 22:39:35
Reply

Marsh Posté le 15-07-2007 à 23:02:12    

Merci beaucoup !!
 
edit : j'ai suivi tes premières recommandations, ça m'a fait prendre conscience de la maladresse de mes opérateurs génériques. après avoir tout rectifié, tout se compile niquel, et j'imagine que ça optimise pas mal (il n'y a plus de copies etc)


Message édité par Vel-Ryphon le 15-07-2007 à 23:09:17
Reply

Marsh Posté le 16-07-2007 à 07:39:28    

Arg j'ai un nouveau problème   :fou:  
 
Voici mon opérateur :
 

Code :
  1. template <class type> Coord_3D<type>&
  2. Coord_3D<type>::operator +(const Coord_3D<type>& value)
  3. {
  4.  Coord_3D<type>& result (x+value.x, y+value.y, z+value.z);
  5.  return result;
  6. }


 
Et voici mon appel :
 

Code :
  1. Coord_3D<float>&
  2. cubic_interpolation_with_tangent(const Coord_3D<float>& start_value, const Coord_3D<float>& start_derivative, const Coord_3D<float>& end_value, const Coord_3D<float>& end_derivative, const float& interpolation_coefficient, const Coord_3D<float>& tangent)
  3. {
  4.  ...
  5.  Coord_3D<float> a  =start_value;
  6.  Coord_3D<float> b  =start_value + start_derivative;
  7.  ...


 
J'obtiens l'erreur suivante :
 

Code :
  1. 'operator+' not implemented in type 'Coord_3D<float> for arguments of the same type in function cubic_interpolation_with_tangent'


 
Si je fais :
 

Code :
  1. Coord_3D<float> a  =start_value;
  2.  Coord_3D<float> b  =a + start_derivative;


 
Y'a pas de souci. CA vient donc du fait que ce soit une référence, je suppose. Mais comment améliorer ma surcharge d'opérateur pour que la première écriture compile ?

Reply

Marsh Posté le 16-07-2007 à 10:12:42    

oulà le  
 
Coord_3D<type> &result   (x+value.x, y+value.y, z+value.z);
 
est pas bien joli joli
 
si c'est une variable temporaire, y'a pas à avoir de &
le & en passage évite les recopies, et en retour c'est que tu te retounes toi-même car tu existeras toujours même après le retour :D (return *this).
 
ensuite, il vaut mieux faire l'opérateur +=, car de l'opérateur += peut découler l'opérateur +.

Reply

Marsh Posté le 16-07-2007 à 10:14:38    

bon le mieux, c'est comme d'hab tu regardes boost:
 
http://www.boost.org/libs/utility/operators.htm
 
ils t'indiquent quels operateurs surcharger, et ils s'occupent du reste :D

Reply

Marsh Posté le 16-07-2007 à 19:35:28    

bjone a écrit :

oulà le  
 
Coord_3D<type> &result   (x+value.x, y+value.y, z+value.z);
 
est pas bien joli joli
 
si c'est une variable temporaire, y'a pas à avoir de &
le & en passage évite les recopies, et en retour c'est que tu te retounes toi-même car tu existeras toujours même après le retour :D (return *this).
 
ensuite, il vaut mieux faire l'opérateur +=, car de l'opérateur += peut découler l'opérateur +.


 
 
mais vu qu'il s'agit de l'opérateur +, je ne veux pas que l'opérateur modifie les variables de la classe appelante, donc le return this n'a pas lieu d'être.
 
J'ai encore un peu de mal avec le concept de référence.
 
Dans mon exemple, si je fais :
 

Code :
  1. 1.
  2.       template <class type> Coord_3D<type>&
  3.    2.
  4.           Coord_3D<type>::operator +(const Coord_3D<type>& value)
  5.    3.
  6.           {
  7.    4.
  8.               Coord_3D<type> result    (x+value.x, y+value.y, z+value.z);
  9.    5.
  10.      
  11.    6.
  12.               return result;
  13.    7.
  14.           }


 
Donc, si j'enlève le &, est-ce que cela va changer quelque chose sur le plan mémoire ? je souhaite éviter le maximum de copie etc, je veux juste qu'il renvoie la variable qu'il vient d'instancer, sans la dupliquer dans une autre.

Reply

Marsh Posté le 16-07-2007 à 23:49:21    

déjà c'est pas légal/logique, puisque ce serait une référence sur un objet temporaire. le & ou * implique un objet persistant au retour de la fonction.
 
regarde la page de boost.
 
tu implémente les += -=, etc et tu hérites de boost::operators<>

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed