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 :

Objet detruit deux fois dans un for_each ?


Sujet :

SL & STL C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Objet detruit deux fois dans un for_each ?
    Bien le bonjour,
    Je viens de tomber sur un `os`, en utilisant pour la premiere fois le for_each de la STL <algorithm>, le destructeur de l'objet function que je lui donne se retrouve appele, par deux fois, a l'interieur du foreach.
    Je remercie par avance quelqu'un sachant m'expliquer pourquoi.

    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
    #include <vector>
    #include <iostream>
    #include <algorithm>
    using namespace std;
     
    class Sum
    {
      int val;
     
    public:
      Sum() : val(0)
        { cout << "CTOR" << endl; }
      Sum(int i) : val(i)
        { cout << "CTOR int" << endl; }
     
      ~Sum()
        { cout << "DTOR" << endl; }
     
      operator int() const
        { return val; }  // extract value                                                                                                         
     
      int operator()(int i)
        { return val += i; }  // application                                                                                                      
    };
     
    void    f(vector<int> v)
    {
      cout << "START" << endl;
      Sum s = 0;  // initial value 0                                                                                                              
     
      s = for_each(v.begin(), v.end(), s);  // gather the sum of all elements                                                                     
      cout << "the sum is " << s << "\n";
      cout << "STOP" << endl;
    }
     
    void    g(vector<int> v)
    {
      cout << endl << "OR EVEN" << endl << "START" << endl;
      cout << "the sum is " << for_each(v.begin(), v.end(), Sum(0)) << "\n";
      cout << "STOP";
    }
     
    int main()
    {
      vector<int>   v;
     
      v.push_back(21);
      v.push_back(42);
      f(v);
      g(v);
    }
    Rapide explication du code, extremement proche d'un copie-colle de Stroustrup, http://www.research.att.com/~bs/bs_f...unction-object
    :
    On applique un for_each a un vector, en lui donnant en troismeme parametre un objet function qui fait la somme de ses elements, la fonction f le fait par une methode, le g par une plus concise mais donnant plus ou moins le meme resultat : le destructeur de Sum est appelle deux fois dans le for_each, une troismeme fois pour la fonction 'f', en toute normalitee, a la sortie du scope.

    Voila la sortie :

    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
    START
    CTOR int
    DTOR
    DTOR
    the sum is 63
    STOP
    DTOR
     
    OR EVEN
    START
    CTOR int
    the sum is 63
    DTOR
    DTOR
    STOP
    Merci a tous, et desole pour mon clavier QWERTY

  2. #2
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Hum, oui
    Hum, oops, on a trouve notre probleme
    Forcement, si on en fait une classe canonique avec des cout dans le constructeur par copie, on comprend beaucoup mieux :

    START
    CTOR int
    COPY CTOR
    COPY CTOR
    operator=
    DTOR
    DTOR
    the sum is 63
    STOP
    DTOR

    OR EVEN
    START
    CTOR int
    COPY CTOR
    the sum is 63
    DTOR
    DTOR
    STOP

    Trois ctor, trois dtor, deux ctor, deux dtor... le compte y est.

    Merci a tous quand meme (o:
    Bonne fin de soiree.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Points : 1 069
    Points
    1 069
    Par défaut
    Par défaut, le compilateur définit un constructeur par copie.
    Il est appelé pour chaque passage d'arguments par valeur ou pour les retours par valeur.
    Définis un constructeur par copie, ajoute y une trace et tu verras qu'il y a autant de destructeurs que de constructeurs.
    Edit: Bon bah tu as été plus rapide.

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

Discussions similaires

  1. MSCRM 4.0 : utiliser un champ deux fois dans un formulaire
    Par irid dans le forum Microsoft Dynamics CRM
    Réponses: 4
    Dernier message: 09/06/2010, 10h39
  2. Recuperer les ligne unique(pas deux fois dans la base)
    Par Zouko dans le forum Langage SQL
    Réponses: 1
    Dernier message: 30/05/2008, 12h17
  3. boucle while - passe deux fois dans la boucle.
    Par Benji01 dans le forum VBA Access
    Réponses: 2
    Dernier message: 05/05/2008, 12h23
  4. [MySQL] Passer deux fois dans une boucle
    Par Henry9 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 19/07/2007, 16h40
  5. Réponses: 1
    Dernier message: 18/06/2007, 09h08

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