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 :

Appel direct au constructeur


Sujet :

C++

  1. #1
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut Appel direct au constructeur/destructeur
    Salut,

    Pouvez-vous m'expliquer 'le pourquoi' des erreurs que j'obtiens en compilant avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g++ -Wall -Wextra monFichier.cpp
    le code ci-dessous :
    Code monFichier.cpp : 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
     
    #include  <cstdio.h> /* error: cstddef.h: No such file or directory */
    #include  <stdio.h>  /* Aucun probleme ... */
     
    class foo
    {
    	int a;
    	int b;
     
    	public:
    		foo()
    		{
    			a = 0;
    			b = 0;
    		}
    		void init()
    		{
    			a = 0;
    			b = 0;
    		}
    		void func()
    		{
    			this->foo(); /* error: invalid use of ‘class foo’ */
    			this->init();/* suis-je obligé de dupliquer le constructeur
    					sous un autre nom pour pouvoir faire le même
    					traitement ? */
    			/* ... */
    		}
    };
     
    int main()
    {
    	foo bar;
     
    	bar.func();
     
    	return 0;
    }

  2. #2
    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 : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    cstdio, pas cstdio.h

    Ensuite, on appelle pas un constructeur, il est appelé automatiquement lors de la construction.

  3. #3
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Dans mon cas le constructeur ne fait que des initialisations, à l'intérieur de mes autres méthodes j'ai besoin de réinitialiser mes données privées je pensais donc pouvoir appeler le constructeur au lieu de le dupliquer sous un autre nom, pourquoi pas ? puisque l'appel explicite au destructeur fonctionne très bien.

    Merci.

  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 : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    L'appel direct au destructeur, c'est la même chose, à éviter.
    Tu as un problème de conception, tu prends le problème à l'envers. Le constructeur sert à construire l'objet, pas à le réinitialiser. Idem pour le destructeur.

  5. #5
    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
    Pour réinitialiser, tu fais un nouvel objet que tu réassignes ou swappe.

  6. #6
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Bonne idée !
    Merci à vous deux.

  7. #7
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Pour la justification, c'est car un constructeur n'a pas de nom, ca va donc être difficile de l'appeler.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  8. #8
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Mon vrai souci était que je voulais définir plusieurs constructeurs, devant tous faire d'abord le même traitement que celui du constructeur par défaut ( à savoir initialiser mes données privées ) puis quelques traitements supplémentaires, j'aurais préféré faire un appel au lieu de copier/coller le corps de mon constructeur par défaut, enfin bref je ne saisis pas ce que vous voulez dire par "un constructeur n'a pas de nom" il porte bien le nom de la classe non ?

    on peut très bien appeler des constructeurs comme ici par exemple :
    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
     
    #include  <iostream>
    using namespace std;
     
    class foo
    {
    	public:
    		foo(int c, int d)
    		{
    			a = c*d;
    			b = c+d;
    		}
    	private:
    		int a,b;
    };
     
    int main()
    {
    	foo *bar = new foo(1,2);
     
    	delete bar,bar = NULL;
     
    	return 0;
    }
    <Hors-Sujet>
    En lisant la FAQ j'ai remarqué des liens cassés (menant vers des trucs de C) comme dans :
    Quel livre acheter ou lire ?
    Où puis-je trouver des cours à télécharger et à consulter ?
    Où trouver la solution des exercices du livre "Le langage C++" de Stroustrup ?
    </Hors-Sujet>

  9. #9
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 941
    Par défaut
    Ca n'a pas de sens d'appeller un contructeur autrement que pour créer un objet.

    Pour éviter de dupliquer du code, tu peux créer une fonction qui te sert à réinitialiser les variables de l'objet, et l'appeler dans tes différents constructeur, c'est plus propre que du copier/coller.

  10. #10
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    L'appel direct au destructeur, c'est la même chose, à éviter.
    <...>
    Imaginons que j'ai une liste chaînée avec un destructeur qui parcours la liste tout en supprimant les noeuds et que j'ai a surchargé l'opérateur = pour pouvoir copier une liste dans une autre comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    a : 1 > 2 > 3 > 4 > NULL
    b : 9 > 10 > NULL
    a = b;
    a : 9 > 10 > NULL
    b : 9 > 10 > NULL
    vous l'aurais compris je dois d'abord vider la liste a, cela implique un appel au destructeur non ? devrais-je dupliquer le destructeur sous un autre nom ( clear() par exemple ) ?

  11. #11
    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 : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Dans le destructeur, tu appelles la méthode clear(), tu ne dupliques pas le code. C'est aussi ce qui est fait pour la STL. Tu as une méthode clear() qui efface le contenu de la liste, et le destructeur n'est pas une redite de cette méthode.

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Pour l'opérateur = , je serais du genre à utiliser l'idiome copy-and-swap, malgré la consommation mémoire supplémentaire (puisqu'on duplique avant de détruire l'existant).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par ssmario2 Voir le message
    Imaginons que j'ai une liste chaînée avec un destructeur qui parcours la liste tout en supprimant les noeuds et que j'ai a surchargé l'opérateur = pour pouvoir copier une liste dans une autre comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    a : 1 > 2 > 3 > 4 > NULL
    b : 9 > 10 > NULL
    a = b;
    a : 9 > 10 > NULL
    b : 9 > 10 > NULL
    vous l'aurais compris je dois d'abord vider la liste a, cela implique un appel au destructeur non ? devrais-je dupliquer le destructeur sous un autre nom ( clear() par exemple ) ?
    En fait, il faut faire la distinction entre le contenu (les éléments de la liste) et le contenant (la liste elle-même)

    Tu peux vouloir vider la liste (AKA détruire son contenu et la remettre dans un état "vide") sans pour autant détruire la variable qui la représente, mais, si tu détruit la variable qui représente la liste, tu dois effectivement en détruire le contenu.

    Comme indiqué plus haut, c'est donc le destructeur (qui est appelé automatiquement lorsque la variable est détruite, parce que l'on sort de la portée dans laquelle elle est déclarée ou par appel explicite à delete) qui va appeler la fonction qui prend en charge la suppression du contenu de la liste, et non l'inverse
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  14. #14
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Merci à vous tous

  15. #15
    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
    Pour l'opérateur = , je serais du genre à utiliser l'idiome copy-and-swap, malgré la consommation mémoire supplémentaire (puisqu'on duplique avant de détruire l'existant).
    Ce qui est nécessaire pour avoir une sémantique rollback face aux exceptions.

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 13/10/2007, 11h37
  2. Appel direct d'une méthode mappée dans un LookupDispatchAction ?
    Par petitpasdelune dans le forum Struts 1
    Réponses: 8
    Dernier message: 22/06/2006, 19h25
  3. Appel d'un constructeur à partir d'un autre
    Par Pragmateek dans le forum Langage
    Réponses: 28
    Dernier message: 18/06/2006, 01h07
  4. Réponses: 5
    Dernier message: 29/04/2006, 21h41
  5. Appel recursif au constructeur
    Par Math75 dans le forum C++
    Réponses: 1
    Dernier message: 11/10/2005, 15h48

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