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 :

Passage paramètre, return, ref, var etc


Sujet :

C++

  1. #1
    Membre éprouvé Avatar de Harooold
    Homme Profil pro
    Ingénieur 3D temps réel
    Inscrit en
    Mars 2008
    Messages
    136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2008
    Messages : 136
    Par défaut Passage paramètre, return, ref, var etc
    Bonjour à tous,

    J'ai été emmené à me poser une question à laquelle je n'arrive pas à répondre...
    J'ai une petite classe génerique dont je suis ammené à passer en paramètre régulièrement :

    Voilà le template, avec quelques opérateur redéfinis, rien de méchant.
    Elle permet de créer un vecteur borné de N élements de type T

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    template <class T, int N>
    class BornedVector
    {
    protected:
       T _v[N];
     
    public:
     
       BornedVector ( ) { }
     
       BornedVector(const BornedVector <T, N> & v)
       {
          for(int i = 0; i < N; ++i)
             _v[i] = v._v[i];
       }
     
       virtual ~BornedVector ( ) { }
     
       inline T & operator []( unsigned int index ) { return _v[index]; }
     
       inline bool operator< ( const BornedVector <T, N> & v ) const
       {
          unsigned int index = 0;
          bool equals = true;
     
          while ( equals && index < N )
          {
             equals = (_v[index]._optiVertexIndex == v._v[index]._optiVertexIndex);
     
             if ( equals ) ++index;
          }
     
          if ( equals )
             return false;
          else
             return _v[index]._optiVertexIndex < v._v[index]._optiVertexIndex;
       }
     
       inline bool operator == ( const BornedVector <T, N> & v ) const
       {
          bool equals = true;
          unsigned int i = 0;
          while ( equals && i < N )
          {
             if ( _v[i] != v._v[i] )
                equals = false;
             else
                ++i;
          }
     
          return equals;
       }
     
       inline void operator = ( const BornedVector <T, N> & v )
       {
          for(int i = 0; i < N; ++i)
          {
             _v[i] = v._v[i];
          }
       }
    };
    Et une petite classe héritant du template, représentant un simple vecteur de 3 entier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Vec3i : public BornedVector <int, 3 >
    {
    public:
       Vec3i ( int x = 0, int y = 0, int z = 0 ) : BornedVector <int, 3> ()
       {
          _v[0] = x;
          _v[1] = y;
          _v[2] = z;
       }
     
       inline int & x ( ) { return _v[0]; }
       inline int & y ( ) { return _v[1]; }
       inline int & z ( ) { return _v[2]; }
    };
    Voilà pour les présentations,
    Ce qui me semble sombre est lors de la manipulation de mon Vec3i.
    Prenons une fonction qui me construit et retourne un Vec3i :
    J'ai changé le noms de fonction et les ait simplifié pour la lisibilité

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    inline Vec3i f1 ( int x, int y, int z )
    {
        return Vec3i ( x, y , z );
    }
    Que se passe t'il en mémoire ?
    Le constructeur de Vec3i est bien appelé, ce qui est retourné n'est apriori pas une copie de mon Vec3i construit.

    J'ai ensuite un appel de fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    f2 (  f1 ( 1, 2, 3 ), f1 ( 2, 3, 4), f1 ( 3, 4, 5 ) );
    Avec comme corps de fonction f2

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    inline void fonction2 ( Vec3i A, Vec3i B, Vec3i C )
    {
       [...]
    }
    Si je trace l'adresse de mes Vec3i , alors je vois que ceux qui arrivent dans f2 sont les même que ceux qui ont été construits par f1, donc pas de copie.
    Cependant ... A B et C se retrouvent avec des valeurs aléatoire, comme si elle n'avaient jamais été initialisée, ce qui n'est pas le cas car il y a bien eu mon appel de constructeur ...

    En bossant avec les réferences c'est bon, mais j'aimerai bien comprendre ce qu'il se passe dans ce cas là ! :p
    Quelqu'un aurait il une idée ?

    Merci de votre attention,
    Harold

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Pour retourner la valeur de f1, il y a un appel au constructeur de copie, mais qui peut être supprimé, c'est une optimisation.
    Quand tu passes un objet par valeur, il y a aussi un appel au constructeur de copie, qui lui n'a pas le droit d'être supprimé sauf si le compilateur peut prouver que ça ne change RIEN au programme, à part son temps d'exécution.

    Cependant ... A B et C se retrouvent avec des valeurs aléatoire, comme si elle n'avaient jamais été initialisée, ce qui n'est pas le cas car il y a bien eu mon appel de constructeur ...
    Hum, a priori, et après un regard très rapide, je ne vois rien dans ton code qui justifierait ce problème.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    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
    BornedVector c'est du franglais.
    Tu voulais sûrement dire BoundedVector.

    Je te conseillerais personnellement de ne pas définir les constructeurs de copie et par défaut, parce que ceux fournis par défaut par le compilateur conviennent parfaitement.

    Ton operator< est bizarre.

    inline ne sert à rien dans Vec3i.

    Sinon ton code est parfaitement correct.

    Si je trace l'adresse de mes Vec3i , alors je vois que ceux qui arrivent dans f2 sont les même que ceux qui ont été construits par f1, donc pas de copie.
    C'est parce que le compilo fait de la NRVO.

Discussions similaires

  1. [ Struts ] [ Jsp ] [ Javascript ] Passage paramètre
    Par bouchette63 dans le forum Struts 1
    Réponses: 7
    Dernier message: 23/05/2006, 14h04
  2. Exécution d'un prog avec passage paramètres
    Par licorne dans le forum C
    Réponses: 3
    Dernier message: 04/05/2006, 13h05
  3. [SQLSERVER]Pb passage paramètre procédure stockée
    Par galinijay dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 01/08/2005, 11h59
  4. [JSP] Problème passage paramètre
    Par besco dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 13/09/2004, 10h15
  5. Fenêtre enfant MDI : passage paramètre à la création
    Par Orangina dans le forum C++Builder
    Réponses: 3
    Dernier message: 21/07/2004, 11h55

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