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 :

Problème pointeur et instanciation d'objet(new)


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 29
    Points : 26
    Points
    26
    Par défaut Problème pointeur et instanciation d'objet(new)
    Bonjour,

    J'ai un problème lorsque j'essai d'instancier un nouvel objet à l'aide d'un pointeur. Voici l'exemple :

    Note : la classe NoeudListeP est privée mais ses attributs sont public. Ses attributs sont simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    P p; 
    NoeudListeP *suivant;
    Le code ci-haut se trouve dans un .h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    NoeudListeP *nouveau; //création d'un nouveau noeud pointant sur NoeudListeP. 
    nouveau = debut; //debut étant un pointeur pointant au début de la liste NoeudListeP.
     
    nouveau->suivant = new NoeudListeP(temp->p); //Erreur ici..
    //temp est aussi un pointeur sur la liste : NoeudListeP et p est sont élément-contenu.
    Ceci est au niveau de l'implémentation .cpp.


    J'espère que c'est suffisamment clair...

    merci!

  2. #2
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    1
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 1
    Points : 3
    Points
    3
    Par défaut
    Bonjour,

    Il n'y a rien qui ne me saute au yeux dans le code que je voie.
    Peut être que, si on avait tout le code (au moins les déclarations de toutes les variables utilisée ici) ainsi que l'intitulé de l'erreur retournée par le compilateur - si erreur de compilation, il y a - , ce serait plus clair.


  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour,
    Je crains qu'en l'absence d'information supplémentaire ta question ne relève de la divination. J'aurais 2 pistes :
    -> debut est initialisé à NULL (ou pas du tout initialisé) sur une liste vide et le problème a lieu dès le premier ajout
    -> idem mais avec temp.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 29
    Points : 26
    Points
    26
    Par défaut
    Bonjour,

    Voici l'info demandé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    NoeudListeP *debut; //Pointe sur le début de la liste.
    Ceci se trouve dans le .h, dans une classe Liste qui englobe NoeudListeP. Cette ligne est déclaré comme public directement dans la classe Liste et non dans NoeudListeP, mais après la classe NoeudListeP.


    Pour temp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    NoeudListePortes *temp; //Est déclaré dans la même fct dans laquelle elle est utilisé.
    Voici l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    error C2664: 'Projet1::Liste::NoeudListeP::NoeudListeP(const Projet1::Liste::NoeudListeP &)' : cannot convert parameter 1 from 'Projet1::P' to 'const Projet1::Liste::NoeudListeP &'
            Reason: cannot convert from 'Projet1::P' to 'const Projet1::ListeP::NoeudListeP'
            No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
    mais je crois avoir trouvé la raison de l'erreur, du moins pour la compil :
    Il faut instancier un nouveau noeud sans paramètre, comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    nouveau->suivant = new NoeudListeP();
    //à la place de :nouveau->suivant = new NoeudListeP(temp->p);
    Par contre, je ne suis pas certain de l'impact que ça change au niveau de l'implémentation ?

    Selon moi, lorsqu'il était indiqué : NoeudListeP(temp->p), le nouveau noeud contenait automatiquement la valeur égal à temp->p, qui est l'élément du noeud. Et c'est aussi ça le but. C'est une fonction de surchage de l'opérateur '='.

    En corrigeant l'erreur, est-ce que je me plante au niveau de mon implémentation ?

    merci !

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

    Informations professionnelles :
    Activité : aucun

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

    L'erreur est comme le port salu, ce qui se passe est marqué dessus

    Ici l'erreur t'indique qu'il est impossible de transformer un objet de type P en une référence const vers un objet de type NoeudListeP.

    De toute évidence, tu as, dans NoeudListeP, un constructeur par défaut ne prenant aucun argument et le constructeur par copie.

    Si tu ne les a pas créés, c'est en fait que le compilateur les a implémentés pour toi

    Or, tu essaye de créer un NoeudListeP en lui passant en paramètre temp->p (ou temp est un pointeur vers un NoeudListeP et p est un ... P)...

    L'idéal est donc, étant donné que le but est quand même de créer un NoeudListeP correctement initialisé, de créer un constructeur de NoeudListeP prenant... un P.

    cela se traduirait, au niveau de la définition de NoeudListeP , par un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class NoeudListeP 
    {
        public:
            NoeudListeP (P const & p);
       /*...*/
    }
    qui serait implémenté sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    NoeudListeP::NoeudListeP(P const & p): p(p),next(NULL)
    {
        /* rien d'autre à faire */
    }
    Fais aussi attention au fait que le constructeur par copie implémenté par le compilateur s'il n'en trouve pas de déclaration de ton cru se contente d'appeler le constructeur par copie des différents membres...

    Or, un pointeur est, pour faire simple, rien d'autre une variable numérique ( de type unsigned int / unsigned long ou unsigned long long, selon les implémentations) qui contient... l'adresse à laquelle se trouve... l'objet de type NoeudListeP suivant.

    La copie "logique" d'un pointeur se fait donc... en faisant simplement en sorte que le pointeur original et le pointeur "copie" contiennent... la même adresse.

    Le résultat de cela est que, si, à un moment où un autre, le constructeur par copie de NoeudListeP est appelé, tu aura deux élément qui feront référence au même objet suivant, avec le risque, soit d'essayer de détruire plus d'une fois l'objet suivant (la première fois passera, la seconde fera planter le programme), soit de vouloir accéder à l'élément suivant (depuis la copie, par exemple) alors que l'élément en question a déjà été détruit (depuis l'original, pour suivre l'exemple)... Et cela fera aussi "planter" le programme

    Tu as donc deux solutions pour résoudre ce problème:

    Soit, tu considère ta classe NoeudListeP comme n'étant pas copiable, soit tu mets un oeuvre un comportement qui s'assurera (par copie de l'objet référencé part ton pointeur suivant) que les deux éléments (l'original et la copie) font référence à deux objet "suivant" différents.

    Ce problème apparaitra également au niveau de l'opérateur d'affectation (operator = (NoeudListeP ) ), ce qui fait que, selon l'option choisie, il faudra soit également le déclarer dans l'accessibilité privée sans le définir afin de rendre ta classe non assignable, soit utiliser l'idiome "copy and swap" afin de s'assurer que tout se passe correctement
    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

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 29
    Points : 26
    Points
    26
    Par défaut
    Merci Koala1 pour cette réponse hyper complète comme toujours
    Avec vos réponses, j'ai pu avancer dans mon projet! Merci !

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

Discussions similaires

  1. Problème d'instanciation d'objet
    Par 1974k dans le forum Débuter avec Java
    Réponses: 8
    Dernier message: 27/12/2014, 16h58
  2. [PHP 5.3] Problème d'instanciation d'objet
    Par lecra dans le forum Langage
    Réponses: 2
    Dernier message: 08/05/2011, 14h01
  3. [COM] Problème d'instanciation d'objet COM
    Par lpapouk dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 02/07/2008, 15h14
  4. Problème Pointeurs d'objets
    Par Julien_C++ dans le forum C++/CLI
    Réponses: 6
    Dernier message: 03/08/2007, 16h00
  5. Réponses: 7
    Dernier message: 18/07/2006, 12h23

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