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 :

prob avec constructeur par copie et variable static


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations forums :
    Inscription : Octobre 2007
    Messages : 6
    Points : 3
    Points
    3
    Par défaut prob avec constructeur par copie et variable static
    Bonjour!
    voila mon prob j'ai crée une classe point avec une donnée static compteur qui s'incrémente ds le constructeur et se décrémente dans le destructeur.
    lorque je déclare par exemple point a(2,5) et b(3,6) le compteur affiche 2 càd j'ai deux objets de type point mais si j'ecrit a(2,5) et pointb=a le compteur affiche 1 càd un suel objet je veux comprendre est dans le 2eme cas il y a qu'un seul objet ou deux a et b et merci
    voila mon code source
    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
    #include <iostream.h>
    class point{
    	static int compteur;
    	int x ;
    	int y ;
    public :
    	point (int &, int&) ;
    	void deplace (int, int) ;
    	void affiche () ;
    	~point () ;
    } ;
    int point::compteur=0;
    point::point (int &abs, int &ord)
    {x = abs ; y = ord ;compteur++;
    cout<<"il existe "<<compteur <<" points "<<this<<endl ;
    }
    void point::deplace (int dx, int dy)
    { x = x + dx ; y = y + dy ;
    }
    void point::affiche ()
    { cout << "Je suis en " << x << " " << y << "\n" ;
    }
    point::~point () {compteur--;
    cout<<"il existe "<<compteur <<" points"<<endl ;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /* -------- Utilisation de la classe point -------- */
    main()
    {
    point a(10,55);
    //b(4,5)
    point b=a;
    }

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Bonjour,
    Je pense que du au fait que tu n'as pas définit d'operator=
    Dans ton code, le compilot va le créer à ta place et faire des = sur tout les membre, dont compteur.
    Aprés ca va surement dépendre du compilatur

  3. #3
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Le compilo te créé automatiquement un opérateur d'affectation et copie juste membre à membre. Quand tu créés deux objets, le constructeur est appelé deux fois, ton compteur est donc incrémenté deux fois. Lorsque tu en créé un, et que tu fais : point b=a; Le compilateur copie membre à membre, mais n'incrémente pas ton compteur. Ce que tu dois faire, comme l'a dit Montgaulois, c'est redéfinir l'opérateur = :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Point & Point::operator= (const Point & monPoint)
    {
       x = monPoint.x;
       y = monPoint.y;
       ++compteur;
    }

  4. #4
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations forums :
    Inscription : Octobre 2007
    Messages : 6
    Points : 3
    Points
    3
    Par défaut re
    Merci Mongaulois
    je pense operator = est obligatoire lorsque il y a des pointeurs dans la classe
    en plus une donnée static est une donnée de classe càd il y a un compteur partagé par tous les objets

  5. #5
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations forums :
    Inscription : Octobre 2007
    Messages : 6
    Points : 3
    Points
    3
    Par défaut re
    merci Bakura & Mongaulois
    j'ai compris

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    Il y a quatre méthodes qui sont créées d'office par le compilateur - quel qu'il soit - s'il n'existe aucune méthodes créée par l'utilisateur pour en tenir lieu.

    Ce sont:
    • Le constructeur par défaut (ne prenant aucun paramètre obligatoire) qui ne sera créé que si aucun constructeur "classique" n'est créé par l'utilisateur
    • le constructeur par copie, dont il faut garder en tête que, par défaut, il s'agit d'une copie membre à membre (avec les problème connus en ce qui concerne les pointeurs)
    • le destructeur
    • l'opérateur d'affectation


    Ces quatre méthodes, communément connue sous le nom des big four doivent être implémentées - fusse par le compilateur - afin d'assurer la mise en oeuvre de l'idiome RAII(Ressouces Aquisition Is Initialisation)

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par Bakura Voir le message
    Le compilo te créé automatiquement un opérateur d'affectation et copie juste membre à membre. Quand tu créés deux objets, le constructeur est appelé deux fois, ton compteur est donc incrémenté deux fois. Lorsque tu en créé un, et que tu fais : point b=a; Le compilateur copie membre à membre, mais n'incrémente pas ton compteur. Ce que tu dois faire, comme l'a dit Montgaulois, c'est redéfinir l'opérateur = :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Point & Point::operator= (const Point & monPoint)
    {
       x = monPoint.x;
       y = monPoint.y;
       ++compteur;
    }
    En y réfléchissant , je croit que l'on as dit une bêtise. Ce n'est pas que l'opérateur = qu'il faut redéfinir , mais la création par recopie aussi. L'operateur = ne devrait pas incrémenté compteur.
    sinon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    point a(-1,5);
    point b =a;//indéfinie même avec un operateur = ??? je sais pas
     
    b=a; //compteur++
    b=a; //compteur++
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     point b = a <=> point b(a);//il me semble

  8. #8
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations forums :
    Inscription : Octobre 2007
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    Salut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    point b = a <=> point(const point & a)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    point(const point & a)
    {
        *this=a;
    }
    voila comment j'ai compris la chose d'abord le compilateur fait un copie du point a sous forme de constant càd avec les valeurs de a.x a.y et compteur=1 puis reserve l'espace pour b (on sait que le constructeur et appelé apres la creation de l'objet) puis il transmet les valeurs qui sont déja copiées aux attributs de b cèd ceux du point a .
    il me semble mais ??

  9. #9
    screetch
    Invité(e)
    Par défaut
    tout ce qui est CONSTRUCTEUR doit incrementer le compteur
    tout ce qui est DESTRUCTEUR doit decrementer
    tout ce qui est OPERATEUR DE RECOPIE ne doit pas y toucher, ce n'est pas un nouvel objet.

    Dans la liste que t'a donné koala, il a parlé :

    -d'un constructeur par defaut, vide : celui ci est generé par le compilateur si tu n'en fournis aucun autre. Si tu fournis un constructeur alors il ne sera pas generé, mais tu peux en creer un. Si tu en crées un, c'est un constructeur donc incremente le compteur.
    - d'un constructeur par recopie : celui ci est generé par le compilateur si tu n'en donnes pas. Celui generé par le compilateur ne fera pas l'incrementation, il faut que tu lui en fournisses un qui fait l'incrementation.
    - d'un destructeur : si tu n'en fournis pas, il sera generé automatiquement, mais tu en as un dans ta classe qui decremente le compteur
    - d'un operateur de recopie : celui ci n'est pas un constructeur. Soit tu en fournis un soit le compilateur le genere pour toi.

  10. #10
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    En y réfléchissant , je croit que l'on as dit une bêtise. Ce n'est pas que l'opérateur = qu'il faut redéfinir , mais la création par recopie aussi. L'operateur = ne devrait pas incrémenté compteur.
    sinon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    point a(-1,5);
    point b =a;//indéfinie même avec un operateur = ??? je sais pas
     
    b=a; //compteur++
    b=a; //compteur++
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     point b = a <=> point b(a);//il me semble
    En effet, j'ai dis une grosse connerie

  11. #11
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations forums :
    Inscription : Octobre 2007
    Messages : 6
    Points : 3
    Points
    3
    Par défaut je pense que c'est Resolu !!
    merci a tous
    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
     
    #include <iostream.h>
    class point{
            int x ;
            int y ;
    public :
            static int compteur;
            point (int , int) ;
            point(const point &p);	
            ~point () ;
     
            } ;
    int point::compteur=0;
    point::point (int abs, int ord) //: x(abs), y(ord),nom(p)
    {
            x = abs ; y = ord ;
            compteur++;
            cout<<"il existe "<<compteur <<" points "<<endl ;
    }
     
    point::point(const point &p)
    {
            this->x = p.x ; this->y = p.y ;
            compteur++;
            cout<<"il existe "<<compteur <<" points "<<endl ;
    }
    point::~point ()
    {
            compteur--;        
            cout<<"il existe "<<compteur <<" points"<<endl ;
    }
    main()
    {
            point a(10,55);  //incrémente le compteur
            point b=a;//incrémente le compteur
            point c(a);    //incrémente le compteur
            a=b;  //n'incréménte pas le compteur 
            cout<<"compteur ="<<point::compteur<<endl<<endl; // affiche le nombre d'ibjets
    }
    ça marche trés bien !

Discussions similaires

  1. Réponses: 24
    Dernier message: 08/05/2008, 17h30
  2. Petit problème avec le constructeur par copie
    Par beegees dans le forum C++
    Réponses: 16
    Dernier message: 01/04/2008, 16h34
  3. [Debutant] Problème avec un constructeur par copie
    Par Drannor dans le forum Débuter
    Réponses: 5
    Dernier message: 12/03/2007, 09h15
  4. Constructeur par copie et std::list
    Par Captain_JS dans le forum SL & STL
    Réponses: 5
    Dernier message: 13/12/2005, 19h15
  5. [deb.]Constructeur par copie
    Par Marc_3 dans le forum Débuter
    Réponses: 4
    Dernier message: 19/11/2005, 13h33

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