question sur les const &

question sur les const & - C++ - Programmation

Marsh Posté le 16-06-2003 à 11:17:49    

salut,
 
Prenons les string comme exemple.
J'ai une fonction avec un paramètre de type const string &.
Quand je passe à la fonction un char * ou une chaine "toto" (donc variable dont le type est différent du paramètre), un objet string est crée et la référence est initialisée à partir de cet objet. Mais pourquoi il faut mettre const pour ca ?
 

Reply

Marsh Posté le 16-06-2003 à 11:17:49   

Reply

Marsh Posté le 16-06-2003 à 11:39:08    

spa obligatoire.
 
const dit juste au compilateur: si le programmeur touche à cette variable tu gueules.
 
comme l'objet est passé par référence (et pas par copie), si tu la modifies tu modifies l'objet de la fonction appellante.  
 
donc vaux mieux éviter ça, car tu si tu le fais cela peut avoir des répercussions bizarres.
 
attention le const est juste un attribut de "lecture seule" synthaxique, tu peux complètement exploser l'objet par des moyens détournés, ça permet UNIQUEMENT au programmeur de se protéger de lui-même.


Message édité par bjone le 16-06-2003 à 11:39:48
Reply

Marsh Posté le 16-06-2003 à 11:39:53    

parce que les objets temporaires ne peuvent être que constant (c'est logique)


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 16-06-2003 à 11:41:54    

pas forcément...
 

Reply

Marsh Posté le 16-06-2003 à 11:44:31    

BJOne a écrit :

pas forcément...
 
 


 
ben si [:spamafote]
Il n'y aurait d'ailleurs aucun interet à pouvoir modifier un objet temporaire.


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 16-06-2003 à 11:47:50    

offff....
 
si l'objet passé en paramètres est juste un pointeur, ou un indice de position dans un tableau, tu peux très bien le modifier...
 
bon c'est sûr par contre, si t'as un objet (plus riche qu'un type prédéfini) est passé par valeur, et qu'il est détruit à la fin de la fonction....
 
enfin c'est suivant le style de programmation...


Message édité par bjone le 16-06-2003 à 11:58:32
Reply

Marsh Posté le 16-06-2003 à 11:55:42    

BJOne a écrit :

offff....
 
si l'objet passé en paramètres est juste un pointeur, ou un indice de position dans un tableau, tu peux très bien le modifier...
 
bon c'est sûr par contre, si t'as un objet (plus riche qu'un type prédéfini) est pas passé par valeur, et qu'il est détruit à la fin de la fonction....
 
enfin c'est suivant le style de programmation...


 
Ben non, c'est pas suivant le style de programation.
Tu peux avoir des paramètre en entrée (qui sont alors des références constantes), ou des paramètres en sortie (ou entrée/sortie, qui sont des références tout court)

Reply

Marsh Posté le 16-06-2003 à 11:55:56    

BJOne a écrit :

offff....
 
 
bon c'est sûr par contre, si t'as un objet (plus riche qu'un type prédéfini) est pas passé par valeur, et qu'il est détruit à la fin de la fonction....


 
Merci de confirmer ce que je disais  :jap:


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 16-06-2003 à 11:57:33    

chui pas d'accord avec le monsieur, tu peux très bien faire un truc comme ça:
 

Code :
  1. parcours(machin *ptr)
  2. {
  3.    while( ptr )
  4.    {
  5.      ....
  6.      ....
  7.      ptr=ptr->suivant;
  8.    }
  9. }

Reply

Marsh Posté le 16-06-2003 à 12:00:41    

BJOne a écrit :

chui pas d'accord avec le monsieur, tu peux très bien faire un truc comme ça:
 

Code :
  1. parcours(machin *ptr)
  2. {
  3.    while( ptr )
  4.    {
  5.      ....
  6.      ....
  7.      ptr=ptr->suivant;
  8.    }
  9. }




 
Et c'est pas un objet, c'est un pointeur sur objet qui n'a rien de temporaire :lol:  
 
Apprends à lire boulay, j'ai bien spécifié "un objet temporaire" dans mon 1er post. Faut arrêter de prendre les gens de haut comme ça....  :sarcastic:  :sarcastic:  :sarcastic:


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 16-06-2003 à 12:00:41   

Reply

Marsh Posté le 16-06-2003 à 12:04:30    

Tetragrammaton IHVH a écrit :


Apprends à lire boulay, j'ai bien spécifié "un objet temporaire" dans mon 1er post. Faut arrêter de prendre les gens de haut comme ça....  :sarcastic:  :sarcastic:  :sarcastic:  


 
Reste à savoir QUI prend les gens de haut... :sarcastic:

Reply

Marsh Posté le 16-06-2003 à 12:06:18    

El_gringo a écrit :


 
Reste à savoir QUI prend les gens de haut... :sarcastic:  


 
pour moi, c'est un mec qui contredit qqn même s'il a tord...  :sarcastic:


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 16-06-2003 à 12:09:12    

Tetragrammaton IHVH a écrit :


pour moi, c'est un mec qui contredit qqn même s'il a tord...  :sarcastic:  


 
...Et pour moi c'est quelqu'un qui saute sur la moindre erreur que peut faire quelqu'un et le traite de gros boulay afin de flatter son ego !
 
EDIT : question de points de vue !


Message édité par El_gringo le 16-06-2003 à 12:13:53
Reply

Marsh Posté le 16-06-2003 à 12:12:52    

bon cool, ça ma saoule y'a toujours prise de tête sur des détails....

Reply

Marsh Posté le 16-06-2003 à 12:13:55    

El_gringo a écrit :


 
...Et pour moi c'est quelqu'un qui saute sur la moindre erreur qui peut faire quelqu'un et le traite de gros boulay afin de flatter son ego !
 
EDIT : question de points de vue !


 
justement, relis le topic en entier et tu verras que je n'ai pas sauté sur la premier erreur, au contraire. Et puis cesse de polluer ce topic.


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 16-06-2003 à 12:17:45    

BJOne a écrit :

spa obligatoire.
 
const dit juste au compilateur: si le programmeur touche à cette variable tu gueules.
 
comme l'objet est passé par référence (et pas par copie), si tu la modifies tu modifies l'objet de la fonction appellante.  
 
donc vaux mieux éviter ça, car tu si tu le fais cela peut avoir des répercussions bizarres.
 
attention le const est juste un attribut de "lecture seule" synthaxique, tu peux complètement exploser l'objet par des moyens détournés, ça permet UNIQUEMENT au programmeur de se protéger de lui-même.


ben vu que ca compile pas, je pense que c'est plutot obligatoire.
 
bon pour essayer de recentrer le debat  :D , si j'ai bien compris comme les variables ne sont du meme type que l'arg de la fonction, un objet temporaire est crée et initialisé avec la valeur de cette variable et comme il s'agit d'un objet temporaire on peut pas le modifier donc faut mettre const.
J'ai bon ?
Mais pourquoi on pourrait pas modifier cet objet ?

Reply

Marsh Posté le 16-06-2003 à 12:20:50    

hellbilly a écrit :


ben vu que ca compile pas, je pense que c'est plutot obligatoire.
 
bon pour essayer de recentrer le debat  :D , si j'ai bien compris comme les variables ne sont du meme type que l'arg de la fonction, un objet temporaire est crée et initialisé avec la valeur de cette variable et comme il s'agit d'un objet temporaire on peut pas le modifier donc faut mettre const.
J'ai bon ?
Mais pourquoi on pourrait pas modifier cet objet ?


 
 :jap:  :jap:  :jap:  
On ne peut pas le modifier car ça servirait à rien étant donné qu'on ne pourrait pas le récuperer au retour de la méthode, c'est pour ça qu'un objet temporaire (comme le cas char* vers string) est créé en constant.


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 16-06-2003 à 12:23:05    

rien ne te l'interdit.
 
par contre QUAND tu sais que ta fonction ne modifies pas un objet passé en référence, il vaux mieux mettre le const (c'est plus clair pour la personne qui passera derrière toi et regardera les classes dans le .h, ou les prototypes de fonctions).
 
symétriquement, le compilo te jetteras sur un cas comme celui ci:

Code :
  1. ma_fonction(objet &a);
  2. fonction_appellante()
  3. {
  4.    const objet t(qqchose);
  5.    ma_fonction(t);
  6. }


 
car t est const, mais le paramètre a ne l'est pas.

Reply

Marsh Posté le 16-06-2003 à 12:23:39    

Tetragrammaton IHVH a écrit :


 
 :jap:  :jap:  :jap:  
On ne peut pas le modifier car ça servirait à rien étant donné qu'on ne pourrait pas le récuperer au retour de la méthode, c'est pour ça qu'un objet temporaire (comme le cas char* vers string) est créé en constant.


 
ouki.
 
là j'avoues que je me souvenais plus que l'objet crée était d'office const (ce qui est, je suis d'accord, logique dans ce cas).


Message édité par bjone le 16-06-2003 à 12:25:22
Reply

Marsh Posté le 16-06-2003 à 12:33:11    

autre cas d'utilité du const: pour les objet temporaire
 

Code :
  1. classs A;
  2. A foo();
  3. void h(const A &a);
  4. void g(A &a);


 
h(foo()) pas de problème
g(foo()) erreur de compilation

Reply

Marsh Posté le 16-06-2003 à 12:37:39    

Tetragrammaton IHVH a écrit :


 
 :jap:  :jap:  :jap:  
On ne peut pas le modifier car ça servirait à rien étant donné qu'on ne pourrait pas le récuperer au retour de la méthode, c'est pour ça qu'un objet temporaire (comme le cas char* vers string) est créé en constant.


 :jap: comprend mieux maintenant

Reply

Marsh Posté le 16-06-2003 à 12:45:45    

BJOne a écrit :

rien ne te l'interdit.
 
par contre QUAND tu sais que ta fonction ne modifies pas un objet passé en référence, il vaux mieux mettre le const (c'est plus clair pour la personne qui passera derrière toi et regardera les classes dans le .h, ou les prototypes de fonctions).
 


J'insiste. Ca ne marche pas si tu ne mets pas const.
 

Code :
  1. class CTest
  2. {
  3. public:
  4. CTest() {}
  5. CTest(char *psz) {}
  6. ~CTest() {}
  7. }
  8. void func(CTest &c) {}
  9. int main()
  10. {
  11. f("foo" ); // Erreur ! -> func(const CTest &c)
  12. }


Message édité par hellbilly le 16-06-2003 à 12:46:36
Reply

Marsh Posté le 16-06-2003 à 12:49:53    

hellbilly a écrit :


J'insiste. Ca ne marche pas si tu ne mets pas const.


 
Tu as raison, mais laisse tomber, bjone n'a pas compris la question. Son exemple montre qu'il confond objet temporaire et objet local.
 
En résumé, en C++, un objet qui n'a pas de nom (et qui vit sur la pile) est constant. Dans ton exemple, l'instance temporaire de CTest, créée sur la pile au moment de l'appel de f(), n'a pas de nom.
 
Sinon, il est toujours possible de créer des objets à la volée avec new mais c'est plus du tout le même problème puisqu'on file une adresse et qu'il faut créer l'objet manuellement.


Message édité par Tetragrammaton IHVH le 16-06-2003 à 13:02:45

---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 16-06-2003 à 13:06:03    

Tetragrammaton IHVH a écrit :


 
Tu as raison, mais laisse tomber, bjone n'a pas compris la question. Son exemple montre qu'il confond objet temporaire et objet local.
 
En résumé, en C++, un objet qui n'a pas de nom (et qui vit sur la pile) est constant. Dans ton exemple, l'instance temporaire de CTest, créée sur la pile au moment de l'appel de f(), n'a pas de nom.
 
Sinon, il est toujours possible de créer des objets à la volée avec new mais c'est plus du tout le même problème puisqu'on file une adresse et qu'il faut créer l'objet manuellement.


 
si j'ai fini par comprendre ce que tu voulais dire...
(d'ailleurs tu n'as pas remarqué le post plus haut)


Message édité par bjone le 16-06-2003 à 13:13:38
Reply

Marsh Posté le 17-06-2003 à 11:55:53    

Code :
  1. struct toto
  2. {
  3. void display(){};
  4. };
  5. toto & traite (toto &t)
  6. {
  7. return t;
  8. }
  9. int main()
  10. {
  11. traite(toto()).display();
  12. return 0;
  13. }


 
Chez moi ca compile et ca s'execute..
 
LeGreg

Reply

Marsh Posté le 17-06-2003 à 12:01:57    

Oops pardon ce n'etait pas *exactement* le meme exemple
que taz:
 

Code :
  1. struct toto
  2. {
  3. void display(){};
  4. };
  5. toto & traite (toto &t)
  6. {
  7. return t;
  8. }
  9. toto foo()
  10. {
  11. return toto();
  12. };
  13. int main()
  14. {
  15. traite(foo()).display();
  16. return 0;
  17. }


 
chez moi ca compile et ca s'execute.
 
LeGreg


Message édité par LeGreg le 17-06-2003 à 12:04:58
Reply

Marsh Posté le 17-06-2003 à 13:01:41    

et alors, tout compile de toute façon. ta mert t'as jamais appris que c'est dangereux de renvoyer des références a des objets locaux?

Reply

Marsh Posté le 17-06-2003 à 13:05:03    

on s'calme, Tetragrammaton avait raison depuis le début ( :jap: m'a trompé de contexte et de vocabulaire)...
c marrant je crois que je n'avais jamais rencontré de prob avec cet histoire de const automatique avec des objets temporaires passés par référence...


Message édité par bjone le 17-06-2003 à 13:08:57
Reply

Marsh Posté le 17-06-2003 à 18:51:31    

++Taz a écrit :

et alors, tout compile de toute façon. ta mert t'as jamais appris que c'est dangereux de renvoyer des références a des objets locaux?


 
C'etait pour les besoins de l'exemple mon pauvre..
(il etait tard et j'ai tout compresse en un seul)
 
je pouvais me satisfaire
d'un traite(foo());
et la pas de probleme a part que ca met
en defaut votre these un peu bizarroide.
 
LeGreg

Reply

Marsh Posté le 17-06-2003 à 19:45:14    

l'es pas bizarre: tu devrais comprendre toi meme ou est le problème

Reply

Marsh Posté le 17-06-2003 à 20:53:24    

++Taz a écrit :

l'es pas bizarre: tu devrais comprendre toi meme ou est le problème


 
le probleme que Tetra et toi avez
c'est que vous assumez que parce que vous
n'avez pas pensé à une utilisation
legale/morale d'une chose que sa simple evocation
en est stupide (surtout que vous n'y avez
reflechi que 5 minutes et que vous n'avez meme pas compile vos
propres exemples).
 
En gros ce que vous dites est valable ("on n'a pas envie de modifier un objet temporaire cree par le compilateur" ) tant qu'on reste a une semantique de valeur.  
C'est vrai, je vous concede que  c'est stupide de penser qu'on puisse vouloir modifier le resultat d'une operation arithmetique telle que (1+2), en plus ce n'est meme pas une l-value.
 
Or des que l'on passe a une semantique de reference, l'argument ne tient plus. Car si vous avez une proxy class, des objets temporaires  il y en a a la pelle et votre argument comme quoi un objet temporaire est forcement const devient intenable. Si ma classe proxy veut etre const-consistant, alors une instance d'un proxy const ne laissera pas modifier son objet et comme la plupart des instances de mon proxy sont des temporaires, ca veut dire qu'il serait, si je vous suivais, la plupart du temps impossible de faire appel a des methodes qui modifierait l'objet auquel mon proxy fait reference.
 
Bref pour revenir a ton exemple Taz:
si j'avais voulu que foo renvoie un objet
constant je l'aurais mis explicitement
en l'etat foo() renvoie un objet temporaire, certes, mais non const.
 
LeGreg

Reply

Marsh Posté le 18-06-2003 à 15:42:00    


 
Tu peux toujours trouver un moyen d'exploiter une faille du compilo avec des cast sur void*  :sarcastic:  
Simplement ça a rien à voir avec la question de hellbilly :sleep:


Message édité par Tetragrammaton IHVH le 18-06-2003 à 15:42:57

---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 18-06-2003 à 15:56:54    

Je peux me tromper mais bon, ce que Tetra et Taz++ essayent de dire, c'est que la norme C++ dit explicitement que le type des objets temporaires crees par le compilateur doit etre "const".
 
 
Apres, si l'exemple donne marche, c'est la faute du compilateur qui ne respecte pas la norme.
 
PS : Je confirme, c'est dans la Bible du C++, a la section 13.3.3.1.4 paragraphe 3


Message édité par Kristoph le 18-06-2003 à 16:34:47
Reply

Marsh Posté le 18-06-2003 à 16:10:14    

Tetragrammaton IHVH a écrit :


 
Simplement ça a rien à voir avec la question de hellbilly :sleep:


Merci ca me rassure, car j'ai vraiment rien capté a ce qu'il a dit  :(

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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