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 :

Retour de variable locale ou membre ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 63
    Par défaut Retour de variable locale ou membre ?
    Bonjour!,
    J'aurais besoin d'un tout petit éclairsissement...

    imaginons :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    class String{
     private: char* value;
     public:
      ...
      char* value(){return value;};
      char* toupper(){
        char tempo[strlen(value)+1]={'\0'};
        for(int i=0;i<strlen(value);t++)
          tempo[i]=toupper(value[i]);
        return tempo;
      };
    };
     
    int main(void){
     String s;
     char *p;
     s = "une valeur";
     s = s.toupper(); //Reaffectation d'une variable locale ?
     p = s.toupper();
     
      ...
      ...
      ...
     
     *p=0; //Dangereux ?
     
     return EXIT_SUCCESS;
    }

    Le but de méthodes telle que toupper est essentiellement de réutiliser immédiatement la valeur de retour pour une assignation.

    Cependant il se pourait que du mauvais code conduise a l'example ou apres un certain temp un pointeur p pointe toujours sur la valeur de retour...

    Ma question est :

    En imaginant que l'operateur = ait été surchargé de façon a copier le contenu de la valeur reçue dans value:

    - Est ce que réaffecter la variable locale tempo est dangereux du fait qu'elle ne soit pas sur le heap ?

    - Idealement vaudrait-il mieu stocker tempo en variable membre de la classe String et l'utiliser pour tout une série d'opérations (qui ne modifient pas la valeur passée) comme toupper, ceci de façon a toujour etre certain de retourner un emplacement mémoire "sur" ?

    - Ceci est-il géré par les compilateur ou les environements récents ?
    - Enfin ceci est-il bon pour la portabilité (systèmes d'exploitations pouvant avoir un mauvais management de la mémoire en général par example) ?


    Voila, c'est une qestion toute bete et je voudrais etre certain de ne pas faire de betises.

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Tu renvoies un pointeur vers une variable locale, ce qui est donc mauvais.

  3. #3
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Si tu utilises la classe std::string, tu n'auras pas de problème, car il y aura une copie par valeur.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 63
    Par défaut
    Citation Envoyé par MatRem Voir le message
    Si tu utilises la classe std::string, tu n'auras pas de problème, car il y aura une copie par valeur.
    Je voudrais etre sur de bien comprendre : la copie par valeur s'éffectue en fait simplement des lors que je vais retourner non plus par pointeur ou par référence, c'est bien ça?

  5. #5
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Effectivement tu as trois façon de renvoyer quelquechose (comme d'ailleurs pour le passage d'aguments) :
    - par pointeur;
    - par référence;
    - par valeur;

    Ensuite on peut utiliser le mot clef const, pour améliorer ces trois "types" d'envoi de données.


    => Si tu utilise le retour par pointeur ou référence tu accédéras, en dehors de la fonction, à la variable elle même (la même instance). Il faut donc absolument qu'elle existe encore après l'appel de la fonction.


    Le retour d'objet locaux à la fonction : qui sont détruits à la fin de l'appel de cette fonction, ne doit donc surtout pas être utilisé dans ce cas.
    En effet, le pointeur ou la référence utiliser après l'appel de fonction sera invalide => erreur de segmentation.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int * f()
    {
       int i; //Allocation automatique sur la pile
       return &i; //Gros problèmes quand on va se servir du pointeur renvoyé. i sera détruit à la fin de sa portée (la fonction).
    }
     
    int main()
    {
       int * pi = f();
       std::cout << *pi << std::endl; // *pi a été alloué puis détruit automatiquement, donc il n'est plus valide ici. => Il y aura trés certainement une erreur de segmentation.
    }

    Par contre tu peux retourner par pointeurs des objets qui sont alloués dynamiquement dans la fonction (new), et non détruit à la fin de l'appel. Cependant il faudra penser à détruire la donnée, en dehors de la fonction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int * f()
    {
       return new int; //Allocation manuelle (dynamique)
    }
     
    int main()
    {
       int * pi = f();
       std::cout << *pi << std::endl; // *pi a été alloué dynamiquement par f, donc il est encore valide.
       delete pi;
    }

    => Enfin tu peux retourner l'objet par valeur. Dans ce cas, il y aura une copie, qui pour les types défini par l'utilisateur (classe) sera fait en appellant le constructeur par copie (C::C(C const &));
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int f()
    {
       int i;
       return i; //Retour par valeur, la variable affectée par le retour copiera la valeur de i.
    }
    int main()
    {
       int i = f(); // copie de la valeur de i dans f;
       std::cout << i << std::endl; //i est valide car il s'agit du i défini dans main;
    }

    J'espère que j'ai été à peu prés clair

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 63
    Par défaut
    Oui c'est parfait.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 20/07/2013, 14h36
  2. Retour d'une variable locale
    Par Arwel dans le forum C
    Réponses: 5
    Dernier message: 16/05/2010, 17h23
  3. "class" vector à indice variable et fonction membr
    Par icetechnik dans le forum C++
    Réponses: 14
    Dernier message: 25/11/2005, 23h46
  4. retour de variable d'une fonction
    Par thunderblade dans le forum ASP
    Réponses: 4
    Dernier message: 28/04/2005, 13h27
  5. variables locales ou globales ???
    Par elvivo dans le forum C
    Réponses: 13
    Dernier message: 03/07/2002, 08h22

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