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

SL & STL C++ Discussion :

Question sur les vectors


Sujet :

SL & STL C++

  1. #1
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut Question sur les vectors
    Salut!

    J'ai besoin de faire une fonction qui crée et initialise aléatoirement un vector d'entiers.
    Je me demandais:
    1)Faut il créer le vector d'une manière particulière pour qu'il reste valide à la sortie de la fonction?
    En C il faut l'allouer dynamiquement pour l'utiliser à la sortie de la fonction, est-ce que pour les vectors on peut se contenter de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<int> vecteur;
    2)Faut il renvoyer un pointeur sur le vector créé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::vector<int>* p_vecteur=&vecteur;
    return p_vecteur;
    ou peut on se contenter de:
    3)Dans ce cas le retour fera il une copie de "vecteur" dans la variable qui recevra le retour de la fonction ou le passage se fera il par référence comme les paramètres de fonction?

    Merci de votre aide.

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    std::vector est un type copiable, donc comme n'importe quel type copiable (un int, un std::string, ...) il peut être renvoyé par valeur par une fonction, et c'est bien une copie qui sera faite.

    Si tu veux éviter la copie, pour des raisons de performances, tu peux toujours passer ton vecteur par référence et simplement le remplir dans la fonction.

  3. #3
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Merci de la réponse mais je préfère que la fonction fasse tout.
    Donc il me faut renvoyer un pointeur pour éviter la copie?

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Attention, si tu crées ton vecteur dans la fonction comme une variable locale, prendre un vecteur sur lui ne sert à rien car la variable est détruite à la sortie de la fonction.
    comme Laurent le dit si bien, soit tu retournes par valeur, soit tu passes en argument par référence le vecteur à remplir.

  5. #5
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    OK, donc j'en revient à la première question:
    comment le créer afin qu'il reste exploitable à la sortie de la fonction?
    Comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vector<int>* p=new vector<int> (10);
    return p;
    ?

  6. #6
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    2 solutions - on ne fait pas trop de pointeur sur un vecteur -
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::vector<int> maFonction()
    {
      std::vector<int> monVecteur;
    /// Mon code
      return monVecteur;
    }
    Auquel cas le vecteur sera créé puis copié dans le nouveau vecteur dans la fonction appelante.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void maFonction(std::<int>& monVecteur)
    {
    /// Mon code
    }
     
    void fonctionAppelante()
    {
      std::vector<int> vecteur;
      maFonction(vecteur);
    /// Le reste du code
    }

  7. #7
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Oui mais:
    -je veux éviter la recopie à la sortie de la fonction;
    -la fonction doit tout faire:créer et initialiser le vector.

    Donc est-ce que la création avec "new" le rend exploitable à la sortie au travers du pointeur?

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Qu'est-ce qui te gêne avec le passage par référence ?

    Il n'y a absolument aucune différence :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Retour de fonction
    std::vector<int> Ret;
    Ret = Fonction();
     
    // Passage par référence
    std::vector<int> Ret;
    Fonction(Ret);
    Créer un vector dynamiquement juste pour éviter une copie en retour de fonction, c'est à oublier.

  9. #9
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Oui en effet, je me suis mal exprimé.
    En fait voici mon prototype:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    generateVector(int size,int min,int max)
    (je n'ai pas mit encore le type de retour)
    La fonction crée un vector de "size" entiers compris entre "min" et "max".
    Et j'aimerais m'y tenir, c'est pour cela que le passage d'une référence sur un vector en paramètre me gêne.
    Bref, ce qui me tente c'est de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    vector<int>* generateVector(...){
                     vector<int>* p=new vector<int> (10);
                     ...
                     return p;
                     }
     
     
     
     
    int main()
    {
    vector<int>* p_vecteur=generateVector(10,1,5);
    Est-ce valide?

  10. #10
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Si vraiment tu veux utiliser le retour par valeur et éviter la copie, tu peux toujours utiliser la feinte de sioux suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::vector<int> Ret;
    Fonction().swap(Ret);

  11. #11
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    C'est valide, mais il faudra penser à détruire le vector ensuite.

    La fonction crée un vector de "size" entiers compris entre "min" et "max".
    Et j'aimerais m'y tenir, c'est pour cela que le passage d'une référence sur un vector en paramètre me gêne.
    Je ne comprends toujours pas ce qui te gêne... Que ta fonction dimensionne et remplisse un vecteur qu'elle a reçu en paramètre, ou qu'elle le fasse sur un vecteur qu'elle a créé, où est la différence ?

  12. #12
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Citation Envoyé par Laurent Gomila
    Si vraiment tu veux utiliser le retour par valeur et éviter la copie, tu peux toujours utiliser la feinte de sioux suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::vector<int> Ret;
    Fonction().swap(Ret);
    Et là il n'y a pas de création d'un vector supplémentaire?
    Je me demande si cela n'est pas équivalent à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::vector<int> Ret;
    std::vector<int> intermediaire;
    intermediaire=Fonction();
    intermediaire.swap(Ret);
    ?
    Je me demande si il n'y a pas création d'un objet intermédiaire, le retour de la fonction, au niveau de "Fonction()".

    De plus, comment être sur que l'adresse du vector retournée est valide?
    Car "swap" ne fait qu'échanger les addresses.

  13. #13
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Je me demande si il n'y a pas création d'un objet intermédiaire, le retour de la fonction, au niveau de "Fonction()".
    C'est ce que je me suis demandé aussi, mais a priori non.

    De plus, comment être sur que l'adresse du vector retournée est valide?
    Car "swap" ne fait qu'échanger les addresses.
    Il ne faut pas tout confondre. Le vecteur retourné sera forcément valide, je ne vois pas comment il pourrait ne pas l'être (à partir du moment où tu ne fais pas n'importe quoi dans ta fonction).
    Swap ne fait qu'échanger des adresses, mais ça tu n'es pas obligé de le savoir. Tout ce qu'il faut savoir c'est qu'il échange le contenu de deux vecteurs, et qu'il n'y a donc pas de recopie.

    Mais pourquoi diable ne pas vouloir ce passage par référence

  14. #14
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Donc je crois que l'astuce est pas mal mais j'ai peur qu'elle ne soit pas aussi efficace qu'un retour de pointeur.

    Sinon si je m'entête pour ne pas mettre de vector en paramètre c'est pour la propreté du code.
    J'aime avoir des fonctions avec le moins de paramètres possible à efficacité égale.

    Mais pour qu'elle fonctionne faut il que le vector soit déclaré avec "new" obligatoirement?

    Je pense que oui car un vector déclaré de manière "classique" sera détruit à la sortie de la fonction, et du coup même si je récupère son addresse elle sera invalide cette fois.

  15. #15
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Quand je fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<int>* generateVector(int size,int min,int max)
    il m'indique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    expected constructor, destructor, or type conversion before '<' token

  16. #16
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    std:: ?
    #include <vector> ?

    Si tu veux la propreté du code, tu fais un retour par valeur et tu prends le constructeur par copie. Ton histoire de pointeur, c'est bien, mais c'est sale pour éviter qqch qui est inutile sauf si tu démontres le contraire.

  17. #17
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Donc si je veux éviter pointeur et recopie il faut que j'utilise le "swap"?

  18. #18
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Oui, mais c'est un hack
    D'abord vérifie que c'est bien un goulot d'étranglement, et ensuite optimise.

  19. #19
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Oui, mais c'est un hack
    C'est à dire, ç'est pas fiable à 100%?

  20. #20
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Si c'est fiable, mais c'est de la bidouille, c'est tout sauf intuitif. Surtout que...

    Sinon si je m'entête pour ne pas mettre de vector en paramètre c'est pour la propreté du code
    On ne doit pas avoir la même conception d'un code propre. Pour moi le passage par référence l'est tout à fait, le swap par contre est cradingue.

    Et puis comme le dit Miles, est-ce qu'il est réellement nécessaire d'éviter cette copie ?

    Je suis désolé, mais là honêtement tu fais de la résistance pour rien, ce serait tellement plus simple de faire comme il faut

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Question sur les Vector
    Par lazins dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 03/10/2008, 09h07
  2. question sur les listes/set/vector
    Par deubelte dans le forum SL & STL
    Réponses: 11
    Dernier message: 04/01/2007, 20h41
  3. question sur les listes/set/vector
    Par deubelte dans le forum SL & STL
    Réponses: 16
    Dernier message: 28/12/2006, 20h17
  4. [debutant STL] question sur les vectors
    Par killerjeff dans le forum SL & STL
    Réponses: 13
    Dernier message: 19/08/2004, 17h32
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

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