const, reference etc , g du mal.

const, reference etc , g du mal. - C++ - Programmation

Marsh Posté le 02-02-2003 à 22:48:15    

Citation :

$ g++ mainentier.cpp
mainentier.cpp: In function `int main()':
mainentier.cpp:25: initialization of non-const reference type `class Plist<int> &'
mainentier.cpp:25: from rvalue of type `Plist<int>'
Plist5.cpp:134: in passing argument 1 of `Plist<int>::operator =<int>(Plist<int> &)'


 
 

Code :
  1. Plist<int> p;
  2. p= (search_member(5 , &entier::getval , m ) );


 
la fonction search_member est censé renvoyer une liste d'indices k de la liste m ou m[k].getval()==5
et j'ai cette erreur.
 

Code :
  1. template<class T_Obj,class T_Mem>
  2. Plist<int> search_member(T_Mem value,T_Mem (T_Obj::*pacc)(),Plist<T_Obj> &l)

Reply

Marsh Posté le 02-02-2003 à 22:48:15   

Reply

Marsh Posté le 02-02-2003 à 23:07:04    

Je dirais que ta Plist n'a pas d'operateur d'assignation ad hoc, mais bon là c'est un peu "irma powa" vu le peu de code que tu donnes.


---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
Reply

Marsh Posté le 02-02-2003 à 23:10:55    

Code :
  1. template<class T> void Plist<T>::operator=(Plist &l)
  2. {
  3.   if (&l!=this)
  4.     {
  5.       while (size!=0)
  6. {
  7.   del(1);
  8. };
  9.      
  10.       int s=l.getsize();
  11.       if (s!=0)
  12. {
  13.   for(int i=1;i<=s;i++)
  14.     {
  15.       adde( l[i].clone() );
  16.     };
  17. };
  18.       initit();
  19.     };
  20. };
  21. void Plist<int>::operator=(Plist &l)
  22. {
  23.   if ((&l)!=this)
  24.     {
  25.       while (size!=0)
  26.       {
  27.       del(1);
  28.       };
  29.       int s=l.getsize();
  30.       if (s!=0)
  31. {
  32.   for(int i=1;i<=s;i++)
  33.     {
  34.       adde(new int ( l[i] ));
  35.     };
  36. };
  37.       initit();
  38.     };
  39. };


 
Le vlà.

Reply

Marsh Posté le 02-02-2003 à 23:58:54    

un opérateur d'affetation retourne toujours une référence sur l'objet.
 

Code :
  1. Type &operator = (const Type &t)
  2. {
  3.    if (&t != this)
  4.    {
  5.       /* copie */
  6.    }
  7.    return *this;
  8. }

Reply

Marsh Posté le 03-02-2003 à 00:16:58    

j'ai fait ça pour empecher les trucs genre a=b=c .
Je verrais demain si ça resoud le probleme.

Reply

Marsh Posté le 03-02-2003 à 01:01:55    

Modifie to operateur d'affectation pour prendre en paramètre une const &.
 
Toujours penser const correcteness, ça te protegeras de bugs difficile à trouver autrement :)

Reply

Marsh Posté le 03-02-2003 à 01:06:25    

karim63 a écrit :

j'ai fait ça pour empecher les trucs genre a=b=c .


 
et pourquoi l'empecher ?
C'est le fonctionnement de l'operateur = en standard..
 
LeGreg


---------------
voxel terrain render engine | animation mentor
Reply

Marsh Posté le 03-02-2003 à 08:11:39    

Kristoph a écrit :

Modifie to operateur d'affectation pour prendre en paramètre une const &.
 
Toujours penser const correcteness, ça te protegeras de bugs difficile à trouver autrement :)


 
Je peux pas !
J'ai un iterateur dans l'objet.
En plus ça m'oblige a mettre en const des trucs que je veux pas comme [ ] .

Reply

Marsh Posté le 03-02-2003 à 10:02:25    

Citation :

Je peux pas !
J'ai un iterateur dans l'objet.

mutable.
 

Citation :

En plus ça m'oblige a mettre en const des trucs que je veux pas comme [ ] .

En fournir deux: const et non-const.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 03-02-2003 à 15:55:47    

pour le mutable c'est réglé.
Mais comment tu definis en const et non const ?  
 


Message édité par karim63 le 03-02-2003 à 15:56:40
Reply

Marsh Posté le 03-02-2003 à 15:55:47   

Reply

Marsh Posté le 03-02-2003 à 16:08:38    

Code :
  1. public:
  2.    const T & operator [] (int position) const
  3.    { .... }
  4.    T & operator [] (int position)
  5.    { .... }


 
Il me semble

Reply

Marsh Posté le 03-02-2003 à 18:47:55    

le const en debut de fonction sert a quoi ?

Reply

Marsh Posté le 03-02-2003 à 18:58:43    

Reply

Marsh Posté le 03-02-2003 à 19:28:00    

je comprend rien désolé. :(

Reply

Marsh Posté le 03-02-2003 à 21:43:03    

karim63 a écrit :

je comprend rien désolé. :(  


const truc & ---> c'est une référence constante sur un objet de type truc.
C'est ca que t'as pas compris ?

Reply

Marsh Posté le 03-02-2003 à 22:15:59    

euh je comprend pas en quoi ça va resoudre mon prob.
Je voulais resoudre le prob si dessus.
C'est pas la premiere fois que ça me le fait.
En fait je fait une fonction qui me renvoit un objet (donc pas par reference) et je veux affecter cet objet a une variable definie dans le champ d'appel de la fonction avec le = et il veut pas et me renvoit l'erreur que j'ai donné plus haut.
Le truc absurde c'est que si ma fonction renvoit une reference sur l'objet et bien ça compile avec un warning. Mais evidement c'est pas le truc a faire car theoriquement la place memoire de l'objet pointé par le reference est desalouée en sortant de la fonction (si j'ai bien compris), mais pourtant ça passe.
Et là il me broute alors que a priori c'est moins foireux ce que je tente de faire. [:ddr555]

Reply

Marsh Posté le 04-02-2003 à 04:34:00    

Citation :

Mais evidement c'est pas le truc a faire car theoriquement la place memoire de l'objet pointé par le reference est desalouée en sortant de la fonction (si j'ai bien compris), mais pourtant ça passe.

Seulement si c'est un objet local à la fonction, donc détruit à sa sortie.
 
Ce qu'on te propose permet au compilateur de choisir tout seul un accès constant ou pas.
Si ça ne te conviens pas, donne un exemple de code.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 04-02-2003 à 09:40:38    

Code :
  1. template<class T> Plist<T>& Plist<T>::operator=(Plist &l)
  2. {
  3.   if (&l!=this)
  4.     {
  5.       while (size!=0)
  6. {
  7.   del(1);
  8. };
  9.      
  10.       int s=l.getsize();
  11.       if (s!=0)
  12. {
  13.   for(int i=1;i<=s;i++)
  14.     {
  15.       adde( l[i].clone() );
  16.     };
  17. };
  18.       initit();
  19.     };
  20.     return *this;
  21. };
  22. template<class T_Obj,class T_Mem>
  23. bool test_member(T_Mem value,T_Mem (T_Obj::*pacc)(),T_Obj obj)
  24. {
  25.   return (obj.*pacc)()==value;
  26. };
  27. template<class T_Obj,class T_Mem>
  28. Plist<int> search_member(T_Mem value,T_Mem (T_Obj::*pacc)(),Plist<T_Obj> &l)
  29. {
  30.   int val=value;
  31.   Plist<int> r;
  32.   int n=l.getsize();
  33.   if (n>0)
  34.     {
  35.       l(1);
  36.       for(int i=1;i<=n;i++)
  37. {
  38.   if (test_member(val, pacc, *l )) /*  ((l.getcurrentnode()->getinfo()->*pacc)()==value)*/
  39.     {
  40.       r<<(new int (i));
  41.     };
  42.   ++l;
  43.  };
  44.     };
  45.   return r;
  46. };
  47. //dans le main: (avec m definie avant) comme une liste de type entier. (une classe que j'ai fait).
  48.   Plist<int> p;
  49.   p= (search_member(5 , &entier::getval , m ) );


 
Donc ça ça me donne l'erreur que j'ai cité.

Reply

Marsh Posté le 04-02-2003 à 11:18:30    

karim63 a écrit :

Citation :

$ g++ mainentier.cpp
mainentier.cpp: In function `int main()':
mainentier.cpp:25: initialization of non-const reference type `class Plist<int> &'
mainentier.cpp:25: from rvalue of type `Plist<int>'
Plist5.cpp:134: in passing argument 1 of `Plist<int>::operator =<int>(Plist<int> &)'




 
Le message d'erreur est très clair ( ;) ), ton operateur d'affectation prend en paramètre un T &, cela veut donc dire qu'il demande à modifier ce même paramètre.
 
Maintenant, voyons le message d'erreur : "initialization of non-const reference type `class Plist<int> &' from rvalue of type `Plist<int>'". En C++, il y a 2 types de paramètres que tu peux passer à une fonction : les lvalue et les rvalue. Seul les lvalue peuvent être passées en paramètres à une T &. Mais une rvalue peut être passée à une "const T &". Hors dans ton cas, tu ne disposes que d'une rvalue donc ton opérateur d'affectation ne peut pas être utilisé.
 
En résumé : operator= déclare vouloir modifier son paramètre. Le code que tu as écris lui fourni un paramètre qu'il n'a pas le droit de modifier => modifie ton operateur = pour qu'il prenne en paramètre une const T &.
 
C'est le dernier avertissement, il n'y a pas d'autres solutions :D


Message édité par Kristoph le 04-02-2003 à 11:19:13
Reply

Marsh Posté le 04-02-2003 à 13:38:22    

const T &  mais j'arrive pas en metant des const, le compilateur il est méchant :sweat:
D'ailleurs j'ai fait une erreur et je compredn pas pkoi ça a compiler. J'ai mis Plist& au lieu de Plist<T>& dans le consttructeur de recopie et aussi dans celui d'affectation pourtant ça compile et ça marche [:ddr555]

Reply

Marsh Posté le 04-02-2003 à 14:25:55    

karim63 a écrit :

const T &  mais j'arrive pas en metant des const, le compilateur il est méchant :sweat:


 
Et bien, poste l'erreur dans ce cas la, avec les const.

Reply

Marsh Posté le 09-02-2003 à 19:23:37    

Code :
  1. Plist<int>& Plist<int>::operator=(const Plist<int> &l)
  2. {
  3.   if ((&l)!=this)
  4.     {
  5.       while (size!=0)
  6.       {
  7.       del(1);
  8.       };
  9.       int s=l.getsize();
  10.       if (s!=0)
  11. {
  12.   for(int i=1;i<=s;i++)
  13.     {
  14.       adde(new int ( l[i] ));
  15.     };
  16. };
  17.       initit();
  18.     };
  19.   return *this;
  20. };


 
Je suis coincé là.
 

Code :
  1. template<class T>  T& Plist<T>::operator[](int j)
  2. {
  3.   (*this)(j);
  4.   return *(ncurrent->getinfo());
  5. };


 

Citation :

Plist5.cpp: In method `class Plist<int> & Plist<int>::operator =<int>(const Plist<int> &)':
Plist5.cpp:147: passing `const Plist<int>' as `this' argument of `int & Plist<int>::operator [](int)' discards qualifiers


 
en effet new [untype] accepte pas une valeur pas const apparement.
En fait je comprends pas pkoi ça marche pu vu que y a pas d'erreur ici quand je met aucun const  :heink:  
Je capte rien.
Et je comprends pas pkoi il veut pas prendre un const.
Non faudrait quand même pas que je surcharge l'operateur new ?

Reply

Marsh Posté le 09-02-2003 à 19:28:57    

tu appliques l'operateur [], déclaré non-const, à l, qui lui est const. d'ou le probleme
defini un operateur [] en const dans ta classe

Reply

Marsh Posté le 09-02-2003 à 19:38:39    

ah ok merci.
Mais donc il faut que j'en definisse un const et un pas const c'est ça ?

Reply

Marsh Posté le 09-02-2003 à 19:39:46    

C'est ça oui, il te faut définir 2 fois l'opérateur []

Reply

Marsh Posté le 09-02-2003 à 19:41:09    

Kristoph a écrit :

C'est ça oui, il te faut définir 2 fois l'opérateur []


 
C'est chelou non ? :heink:  
Y a pas un mot clef qui evite la redondance ?


Message édité par karim63 le 09-02-2003 à 19:41:25
Reply

Marsh Posté le 09-02-2003 à 19:43:17    

faut que je mette en double pas mal de fonction alors.

Reply

Marsh Posté le 09-02-2003 à 19:44:28    

karim63 a écrit :


 
C'est chelou non ? :heink:  
Y a pas un mot clef qui evite la redondance ?


c'est pas de la redondance, tu crées un opérateur qui sera utilisé avec les objets const et un autre pour les objets non-const.

Reply

Marsh Posté le 09-02-2003 à 19:47:27    

benh dans ce cas quel est l'interet de differencier les deux ?
Désolé je débute :D

Reply

Marsh Posté le 09-02-2003 à 19:51:01    

'tain la vache va falloir que je fasse pas mal de fonction en double  :wahoo:

Reply

Marsh Posté le 09-02-2003 à 21:00:20    

C bon j'ai pigé le truc. :)

Reply

Marsh Posté le 09-02-2003 à 21:01:22    

karim63 a écrit :

'tain la vache va falloir que je fasse pas mal de fonction en double  :wahoo:  


non, de manière générale, les fonctions ne modifiant pas l'état de l'objet sont déclarées const.
pour certaines fonctions, c'est un peu different. par exemple, l'operateur [] te permet d'accéder à un element, et c'est pratique d'avoir une notation a[] = b. mais tu peux aussi vouloir juste y accéder et dans un contexte constant. c'est pour ca qu'il faut souvent en définir 2 versions const et non const.
Les fonctions const peuvent être utilisees avec des objets const et  non-const, mais les fonctions non-const ne peuvent etre utilisees qu'avec des objets non-const (sauf cast dans certains cas, c'est utile)

Reply

Marsh Posté le 09-02-2003 à 21:15:17    

Code :
  1. T& operator*() const;//renvoie l'objet pointé par l'iterateur


 
y en a qu'une et une const mais pourtant je peux quand même acceder a l'objet courant et le modifier, y a un truc qui m'echape.
par exemple je peut faire.
(*l).valeur=3;
 
Le const a donc pas de rapport avec ce que renvoit la fonction ?
Donc pour l'operateur l[] en fait j'ai pas besoin de la fonction non const vu que la fonction modifie pas l'objet l, à part le neud courant et son indice qui sont en mutable et modifiés par une sous fonction.


Message édité par karim63 le 09-02-2003 à 21:17:38
Reply

Marsh Posté le 09-02-2003 à 21:20:25    

karim63 a écrit :

Code :
  1. T& operator*() const;//renvoie l'objet pointé par l'iterateur


 
y en a qu'une et une const mais pourtant je peux quand même acceder a l'objet courant et le modifier, y a un truc qui m'echape.
par exemple je peut faire.
(*l).valeur=3;
 
Le const a donc pas de rapport avec ce que renvoit la fonction ?
Donc pour l'operateur l[] en fait j'ai pas besoin de la fonction non const vu que la fonction modifie pas l'objet l, à part le neud courant et son indice qui sont en mutable et modifiés par une sous fonction.


la méthode est constante, pas la référence retournée.

Reply

Marsh Posté le 09-02-2003 à 21:24:10    

en fac ils nous ont pas trop pris la tete avec ça.
Ils nous ont pas habitués a mettre un const dés que la fonction est constante.
Faut dire que j'avais une vielle prof de daube :lol:

Reply

Marsh Posté le 10-02-2003 à 05:44:02    

karim63 a écrit :

y en a qu'une et une const mais pourtant je peux quand même acceder a l'objet courant et le modifier, y a un truc qui m'echape.

L'itérateur peut être constant sans que l'objet pointé le soit !
C'est l'équivalent de cette situation:

Code :
  1. int i;
  2. int *const pi= &i; //pointeur constant, sur une variable qui ne l'est pas
  3. *pi= 5; //ok
  4. pi++; //non


 
Si tu veux créer un itérateur sur un conteneur constant (équivalent à un const x*), tu dois en faire une classe séparée.
Ce que fait la STL avec const_iterator.


Message édité par Musaran le 10-02-2003 à 05:44:32

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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