IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Question argument d'une fonction de type string


Sujet :

C++

  1. #21
    Membre �prouv�
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    D�tails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par d�faut
    L'inconvenient ici c'est que l'operateur d'affectation doit etre disponible.
    C'est pas tr�s beau mais c'est pas mal comme astuce.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    int fonction( int ancien, NouvelObjet & nouvelle fonctionnalité);
     
    inline int fonction( int ancien = 1) {
    	NouvelObjet tmp;
    	fonction (ancien, tmp);
    }
    Oui c'est l'une des solution que j'ai d�j� �voqu�.

  2. #22
    Membre chevronn�
    Profil pro
    Inscrit en
    F�vrier 2008
    Messages
    439
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2008
    Messages : 439
    Par d�faut
    Citation Envoy� par Montag Voir le message
    @corrector :
    Pourrais tu expliquer pourquoi :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    class B {};
     
    class A
    {
      void func( B & b = (B()=B()) );
    };
    fonctionne

    D'avance merci
    Tout simplement : dans ce cas d'esp�ce (classe B vide), puisqu'aucun op�rateur d'affectation ("operator=") n'est d�clar�, le compilateur va automatiquement g�n�rer une d�claration, �quivalente � :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    class B {
    public:
    	B& operator= (const B&);
    };
    Remarque : si la classe B avait eu des membres, il en aurait �t� de m�me, du moment qu'aucun membre n'a un op�rateur d'affectation prenant une r�f�rence non-constante (comme auto_ptr).

    Il faut noter � propos d'operator= que :
    1. c'est une fonction membre (forc�ment!)
    2. elle prend une r�f�rence constante
    3. elle renvoie une r�f�rence non-constante

    Le (1) implique qu'il est possible de l'invoquer sur une r-valeur, comme par exemple un temporaire :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    B x;
    B().operator= (x); // fonction membre : ok
    B() = x; // exacactement la même chose, avec une syntaxe plus sympathique
    Le (2) permet �videment de passer une r-valeur :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    B().operator= (B());
    B() = B();
    Le (3) signifie que le r�sultat de l'application de cette fonction est une l-valeur, comme :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    int val();
    int &ref();
    &val(); // erreur : val() est une r-valeur!
    val() = 4; // idem
    &ref(); // ok : ref() est une l-valeur
    ref() = 4; // idem
    Comme "B().operator= (B())" a le type r�f�rence non-constante sur B, c'est une l-valeur non-constante de B, donc on peut lier une r�f�rence non-constante sur B dessus :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    B &ref = (B().operator= (B()));
    B &r = (B() = B());
    donc le code est correct.

  3. #23
    Membre exp�riment�
    Profil pro
    Inscrit en
    Ao�t 2007
    Messages
    190
    D�tails du profil
    Informations personnelles :
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Ao�t 2007
    Messages : 190
    Par d�faut
    Ok, je pense avoir compris, merci beaucoup.

  4. #24
    Membre chevronn�
    Profil pro
    Inscrit en
    F�vrier 2008
    Messages
    439
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2008
    Messages : 439
    Par d�faut
    Citation Envoy� par NiamorH Voir le message
    L'inconvenient ici c'est que l'operateur d'affectation doit etre disponible.
    C'est pas tr�s beau mais c'est pas mal comme astuce.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    int fonction( int ancien, NouvelObjet & nouvelle fonctionnalité);
     
    inline int fonction( int ancien = 1) {
    	NouvelObjet tmp;
    	fonction (ancien, tmp);
    }
    Oui c'est l'une des solution que j'ai d�j� �voqu�.
    C'est juste une fa�on de faire qui marche ici.

    En g�n�ral, c'est plut�t sur des classes qui n'ont pas de notion de copie qu'on a besoin d'une telle chose, notamment ostrstream (traditionnellement)/ostringstream (actuellement).

    En traditionnel :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    char *p = ((ostrstream&)(ostrstream() << ...)).str(); // cast ancien style, c'est du traditionnel!
    Mais ostrstream() est un temporaire, donc si on voulait sortir une classe Date :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    class Date;
    ostream& operator<< (ostream& os, const Date& d);
    �a marchait pas, �videment (r�f�rence li�e � une r-valeur, vous connaissez la musique).

    Alors, on �crivait :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    char *p = ((ostrstream&)(ostrstream() << "" << date << ...)).str();
    parce que la sortie de const char * �tait
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    ostream& ostream::operator<< (const char*)
    donc fonction membre, �a marche, << "" est un NOP, �a nous donne une l-valeur, super.

    Il se trouve, malheureusement, et bizarrement, que le comit�, dont les voies sont vraiment imp�n�trables, a d�cid� qu'il valait mieux que cette fonction soit non-membre (ou alors, il a juste d�cid� �a � "pile-ou-face").

    Donc cette astuce ne fonction plus! Mais il reste heureusement des fonctions qui ne font rien et qui renvoient une r�f�rence sur *this, et d'habitude on utilise flush() pour �a (on en a souvent besoin sur un ostringstream, et flush ne fait strictement rien sur un ostringstream) :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    std::string s = (static_cast<std::ostringstream&>(ostringstream().flush() << ...)).str();

  5. #25
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Citation Envoy� par NiamorH Voir le message
    Absolument pas d'accord.
    Il existe des param�tres en entr�e seule, en sortie seule, et en entr�e/sortie.
    Un lien au hasard : http://www.jaylelillois.info/index.p...chap3&desc=iut
    A vrai dire, cette approche est, certes juste, si on ne se r�f�re qu'aux langages actuels, mais oublie le cheminement qui � men� � ce r�sultat.

    C'est un peu comme si on n'�tudiait l'histoire de l'homme qu'� partir de 1800, en "oubliant" le Moyen-Age, l'antiquit� et la pr�histoire

    Avant que la notion de param�tres n'intervienne, on parlait de proc�dure, et non de fonction.

    Une proc�dure n'avait besoin que d'un nom, et ne n�cessitait ni valeur de retour ni argument pour la simple et bonne raison que les langages qui les proposaient travaillaient... avec des variables globales.

    L'ensemble des proc�dures d'un programme avait donc tout loisir d'acc�der � n'importe quelle variable globale, que ce soit en "lecture" ou en "�criture", avec tous les probl�mes inh�rents � cet �tat de fait.

    Une proc�dure poursuivait alors deux objectifs majeurs:
    • Eviter la recopie d'un code lourd en le rempla�ant par l'appel de la proc�dure
    • permettre qu'un morceau de code puisse n'avoir qu'une responsabilit� clairement d�finie.

    Par la suite, on (quand je dis "on", je parle des p�res fondateurs de la programmation...) a pris conscience des probl�mes inh�rents � l'utilisation de variables globales, et on a d�cid� de les remplacer par des variables locales.

    Cela a impliqu� que l'on r�fl�chisse � "d'autres moyens" en vue de mettre cette d�l�gation de responsabilit�s en oeuvre, � savoir:
    • Etre en mesure de fournir des donn�es n�cessaire � la fonction
    • Etre en mesure de r�cup�rer le r�sultat de la fonction

    La premi�re �tape est devenue le passage d'arguments, et la seconde la valeur de retour.

    Au d�but, il n'est question de passer les arguments que "en entr�e", car le passage d'argument se fait "par valeur", et donc, une fonction ne pouvait donc fournir qu'un seul r�sultat, sous la forme de sa valeur de retour.

    Evidemment, pour "id�al" que soit cet �tat de fait du pur point de vue de la d�l�gation des t�ches, il pr�sentait malgr� tout des inconv�nients majeurs, ne serait-ce que parce qu'il obligeait � �crire un code proche de
    Ou parce qu'il est difficile, quand tout est renvoy� par valeur de pouvoir d�terminer si une structure est valide ou non lors du retour de la fonction.

    C'est alors que le C est apparu et a �mis l'id�e que
    Si nous fournissions comme argument la valeur de l'adresse m�moire � modifier au lieu de la valeur elle-m�me, nous pourrions "r�percuter" les modifications apport�es au sein d'une fonction appel�e � la variable utilis�e par la fonction appelante
    avec pour corolaire le fait que l'on pourrait tr�s bien utiliser la valeur de retour pour signifier la r�ussite ou l'�chec du traitement tout en obtenant la valeur valablement modifi�e... Voire obtenir plusieurs valeurs modifi�es (au d�triment de la d�l�gation des t�ches).

    Le pointeur �tait n�, et avec lui, la notion d'argument "d'entr�e / sortie".

    Mais le pointeur n'est, � l'extr�me, qu'un "sucre syntaxique" permettant de contourner une restriction au niveau des valeurs de retour

    Quand le C++ (mais pas seulement lui) est arriv�, il y avait suffisemment d'exp�rience de pointeurs mal g�r�s pour se rendre compte que le fait de travailler sur "l'adresse m�moire" � laquelle se trouve une variable peut �tre catastrophique, et l'id�e suivante a donc �t� de "permettre de fournir un alias de la variable" comme argument de fonction (sous entendu que toute les modifications apport�es � cet alias seraient r�percut�e sur la variable d'origine): cet alias de variable a pris le nom de r�f�rence en C++.

    Alors, bien sur, maintenant, tout le monde consid�re (du moins, quand on regarde les langages qui "ont le vent en poupe" actuellement) qu'un argument peut �tre en entr�e seule, en entr�e sortie ou en sortie...

    Mais, historiquement parlant, cela n'a absolument pas �t� toujours le cas.

    C'est la raison pour laquelle il est largement pr�f�rable de se rappeler que, bien qu'il soit *maintenant* possible d'envisager un argument "d'entr�e / sortie", �a ne reste "qu'une facilit� apport�e par le langage" parce que le propre d'un argument a toujours �t�... de fournir � la fonction une valeur qu'elle est dans l'incapacit� de d�terminer d'elle-m�me.

    Une fois que tu accepte cette historique (tr�s rapide) et que tu te rappelle d'o� vient le C++, tu te rend compte que l'optique d'interdire une r�f�rence anonyme non constante ou un argument par d�faut fourni sous la forme d'une r�f�rence non constante est la seule optique coh�rente.

    Maintenant, d'autres optiques auraient pu �tre envisag�es, mais elles l'auraient �t� au prix de l'oubli des racines du C++, et les philosophes (et les historiens) nous mettent en garde contre le danger de r�p�ter les erreurs si on oublie trop son pass�
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  6. #26
    Membre chevronn�
    Profil pro
    Inscrit en
    F�vrier 2008
    Messages
    439
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2008
    Messages : 439
    Par d�faut
    Citation Envoy� par koala01 Voir le message
    Une fois que tu accepte cette historique (tr�s rapide) et que tu te rappelle d'o� vient le C++, tu te rend compte que l'optique d'interdire une r�f�rence anonyme non constante ou un argument par d�faut fourni sous la forme d'une r�f�rence non constante est la seule optique coh�rente.
    Je vois mal ce qu'il y a de "coh�rent" � forcer le programmeur � utiliser les diff�rentes astuces que j'ai donn� pour obtenir une l-valeur non-constante sur un temporaire.

  7. #27
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    <rien � voir>
    Citation Envoy� par koala01 Voir le message
    Avant que la notion de param�tres n'intervienne, on parlait de proc�dure, et non de fonction.
    Dans le plus r�cent, je suis tomb� sur le "cours d'algorithmie" de Stepanov (dispo en ligne gratuitement sur son site, avec les sources LaTeX/beamer et tout et tout). Bref, il emploie "proc�dure" pour les routines qui peuvent aussi alt�rer leurs arguments, et "fonctions" pour celles qui ne le peuvent/font pas -- et ce n'est pas du tout dit comme �a.
    </>
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  8. #28
    Membre chevronn�
    Profil pro
    Inscrit en
    F�vrier 2008
    Messages
    439
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2008
    Messages : 439
    Par d�faut
    Citation Envoy� par Luc Hermitte Voir le message
    <rien � voir>Bref, il emploie "proc�dure" pour les routines qui peuvent aussi alt�rer leurs arguments, et "fonctions" pour celles qui ne le peuvent/font pas -- et ce n'est pas du tout dit comme �a.
    </>
    <rien � voir/Ce n'est pas la terminologie Ada, �a? Jean-Marc?/

  9. #29
    Membre �m�rite Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    D�tails du profil
    Informations personnelles :
    �ge : 38
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Par d�faut
    Je trouve cette terminologie bien plus coh�rente, parce qu'on distingue bien les fonctions au sens math�matique ou de programmation fonctionnelle, des proc�dures.

    En l'occurence, un param�tre en entr�e/sortie, c'est souvent pour �viter des recopies redondantes comme dit Koala, ou qu'on ne dispose pas d'un m�canisme simple pour cr�er des n-uplets.

  10. #30
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Citation Envoy� par corrector Voir le message
    Je vois mal ce qu'il y a de "coh�rent" � forcer le programmeur � utiliser les diff�rentes astuces que j'ai donn� pour obtenir une l-valeur non-constante sur un temporaire.
    Le fait que, justement, c'est un objet temporaire que tu veux passer par r�f�rence...

    Il ne faut pas oublier que, en C++ (car l'optique est diff�rente, en C# ou en java, par exemple), une r�f�rence est l'alias d'un objet existant, et qu'un objet est syst�matiquement d�truit lorsque l'on quitte la port�e dans laquelle il est d�clar�.

    Une r�f�rence ne peut donc �tre valide que tant que l'objet auquel elle fait r�f�rence existe, et est utilis�e pour deux raisons particuli�res qui sont:
    • d'�viter la copie de structures de grandes tailles
    • de permettre aux modifications apport�es � la r�f�rence d'�tre r�percut�es vers l'objet d'origine existant dans la fonction appelante

    A partir du moment o� tu ne poursuit pas ces deux objetctifs - et c'est le cas quand tu d�cide de fournir un argument facultatif sous la forme d'une r�f�rence, ne serait-ce que parce que cela implique la cr�ation d'un objet temporaire - je comprend parfaitement(et je laisse tout le monde libre de ne pas �tre d'accord avec moi) que le comit� de normalisation n'ai pas jug� - jusqu'� pr�sent - d'autoriser la modification de cet argument.

    Et la raison qui vient directement � l'esprit est, tout simplement, que tu ne dispose d'aucun moyen de savoir, lorsque tu impl�mente (toi, en tant que programmeur) ta fonction, si l'appel sera fait en passant une r�f�rence sur un objet existant ou si, au contraire, c'est l'argument par d�faut (et donc temporaire) qui est utilis�.

    Bien s�r, tu peux encore "facilement" effectuer un test de valeur sur un membre de cet argument... Mais encore faut-il alors t'assurer que la valeur de l'argument par d�faut n'apparaitra que... dans le cadre de l'argument par d�faut, et ne puisse en aucun cas apparaitre lorsque l'argument est issu d'un objet existant.

    Autrement, tu risque, lors de l'impl�mentation de ta fonction, de partir du principe que "l'argument est tir� d'un objet existant en dehors de la fonction", et de fournir un comportement purement inutile (et potentiellement dangereux) si, d'aventure, ce n'est pas le cas.

    En gros, le comit� n'a donc que pleinement appliqu� le principe du rasoir d'Occam : si tu n'a pas besoin de quelque chose, ne le fais pas

    Cette optique est donc clairement coh�rente avec les autres concepts, m�me si, de fait, d'autres optiques auraient peut �tre pu �tre tout aussi coh�rentes
    Citation Envoy� par Luc Hermitte Voir le message
    <rien � voir>

    Dans le plus r�cent, je suis tomb� sur le "cours d'algorithmie" de Stepanov (dispo en ligne gratuitement sur son site, avec les sources LaTeX/beamer et tout et tout). Bref, il emploie "proc�dure" pour les routines qui peuvent aussi alt�rer leurs arguments, et "fonctions" pour celles qui ne le peuvent/font pas -- et ce n'est pas du tout dit comme �a.
    </>
    Je con�ois sans aucun probl�me que les termes "proc�dure" et "fonction" puissent �tre utilis�s de mani�re pour ainsi dire indiff�rente lorsque l'on ne consid�re que l'algorithmique de mani�re g�n�rale.

    Cependant, un fait reste pr�sent:

    Dans les langages qui utilisent les variables globales (COBOL avec sa procedure division (remarque qu'il ne s'agit pas de la fonction division ), le BASIC tel qu'il �tait pr�sent dans les premier micro, ...) c'est le terme proc�dure qui est syst�matiquement utilis�, avec - effectivement - comme sous entendu qu'une proc�dure est susceptible de modifier n'importe quelle variable.

    Si, dans les langages qui n'utilisent pas exclusivement les variables globales, le terme proc�dure peut �tre utilis�, ce n'est que suite � l'amalgame entre les deux, mais en oubliant que si toute fonction (avec valeur de retour et arguments �ventuels) est une proc�dure "particuli�re", une proc�dure au sens strict n'est pas forc�ment une fonction, car ne disposant pas forc�ment d'une valeur de retour et/ou d'arguments �ventuels.

    Evidemment, on rencontre aussi des langages qui permettent d'office de consid�rer les argument comme �tant "d'entr�e / sortie" (sauf indication contraire), mais, de mani�re g�n�rale, on court moins de risque � penser sous la forme de
    un argument est d'entr�e seule
    que sous celle de
    un argument est syst�matiquement d'entr�e/sortie
    pour la simple et bonne raison que, si un argument est d'entr�e / sortie et qu'on le consid�re comme �tant d'entr�e seule, au pire, on se restreint dans l'utilisation que l'on peut en faire, alors que si on consid�re un argument d'entr�e seule comme �tant un argument d'entr�e/sortie, on s'ouvre la porte � des incompatibilit�s majeures
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  11. #31
    Membre �prouv�
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    D�tails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par d�faut
    Citation Envoy� par koala01 Voir le message
    bla bla bla ... moyen age ... bla bla bla ... inutile ... bla bla bla ... dangereux
    d�sol�, je ne suis pas convaincu.

Discussions similaires

  1. R�ponses: 5
    Dernier message: 14/07/2010, 10h34
  2. R�ponses: 9
    Dernier message: 10/05/2010, 21h35
  3. R�ponses: 11
    Dernier message: 18/02/2007, 15h37
  4. Detecter le type d'un argument d'une fonction
    Par flipper203 dans le forum C++
    R�ponses: 31
    Dernier message: 07/07/2006, 22h53
  5. passer FILE* en argument d une fonction
    Par Monsieur_Manu dans le forum C
    R�ponses: 9
    Dernier message: 10/04/2003, 17h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo