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 :

Instantiation d'un obj dans une liste ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    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
    Par défaut Instantiation d'un obj dans une liste ?
    Bonjour,

    J'ai un problème de logique au niveau de l'instanciation d'un objet qui sera ensuite mis dans une liste. Je me demande où allouer la mémoire pour cet objet ? - Dans la classe de l'objet au niveau du constructeur ou le constructeur de la classe de la liste ?

    Voici un exemple de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Classe Objet{
     
    Objet (Couleur c; Lieu l){ //constructeur
      //Est-ce que je devrais faire "obj1 = new Objet" ici ?
      Couleur color;
      Lieu l;
      }
    }
     
    Classe ListeObjet{
       ListeObjet(){  //Constructeur d'une liste d'objet
       //Est-ce que je devrais plutôt faire "obj1 = new Objet" ici ? 
       }
    }
    merci !

  2. #2
    Membre averti
    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
    Par défaut
    En fait, j'en ajoute un peu
    Le but ici est de faire une surcharge de l'opérateur "=" de deux listes par exemple.

    Donc, si je poste listeObj1 = listeObj2 je veux faire une copie profonde et non une copie de surface(en pointant seulement).

    Pour ça, je dois :
    1. Vider la liste 1.
    2. Créer un nouvel objet pour chaque objet présent dans la liste 2.
    3. Copier chacun des éléments de la liste 2 dans la nouvelle liste crée à partir des nouveaux éléments crées.

    Je cherche, mais je ne vois pas comment copier proprement et en profondeur l'objet de la liste2 sur un objet de la liste 1.....

    merci !

  3. #3
    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
    Salut, et bienvenue sur le forum.

    La réponse va sans doute te surprendre, mais la réponse est "ni l'un, ni l'autre"...

    En effet, il faut te dire que le compilateur connait parfaitement la taille des différents types que tu crées, et qu'il est parfaitement en mesure de faire une addition.

    Comme il connait la taille du type Couleur et celle du type Lieu, et qu'il sait en outre l'espace qui lui est nécessaire pour "caser le reste" venant de Objet, il est parfaitement en mesure de réserver suffisamment d'espace pour représenter l'ensemble du contenu d'objet

    D'un autre coté, il existe des conteneurs, fournis par le standard, qui permettent de gérer des collections d'objet sans même devoir t'inquiéter par toi même de l'espace qu'ils utilisent en mémoire (un p'tit tour vers la FAQ s'impose )

    En fait, l'opérateur new ne s'applique que lorsque tu décide de prendre la responsabiltié totale de la durée de vie de l'objet dont tu demande la création.

    Par exemple, si un objet pouvait ne pas avoir de couleur ou de lieu assigné au moment de la création, il faudrait alors, effectivement, déclarer le membre correspondant sous la forme d'un pointeur, et n'effectuer l'allocation de la mémoire (appeler new sur ce membre) qu'au "moment opportun".

    Cependant, il faut savoir que, surtout si tu débute et que tu ne peux pas profiter d'une certaine expérience issue du C, c'est souvent prendre de très gros risques, soit de créer des fuites mémoires qui finiront à terme par rendre ton système tout à fait instable, soit d'en arriver, en voulant trop bien faire, à des situations dans lesquelles tu essayera de libérer deux fois la mémoire. soit enfin d'en arriver à des situations dans lesquelles le pointeur aura été invalidé parce que, justement, l'adresse mémoire sur laquelle il pointe aura été libérée un peu plus tot.

    Et toutes ces situations sont véritablement des PAC qui reviennent bien souvent à te tirer une balle dans le pied

    Le conseil que je pourrais donc te donner, c'est de travailler autant que possible sans utiliser les pointeurs, ce qui t'évitera une sérieuse montagne de problème, et de ne recourir à l'allocation dynamique de la mémoire que lorsque tu n'a vraiment pas le choix (il existe en effet quelques cas dans lesquels tu n'a pas vraiment le choix).

    Mais, tant que tu n'en sera pas arrivé à ce point de ton apprentissage, contente toi seulement bien des membres géré de manière tout à fait classique
    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

  4. #4
    Membre averti
    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
    Par défaut
    Merci pour ta réponse Koala01!
    Je vais essayer d'éviter les new et pointeurs autant que possible... mais pour l'instant j'essais surtout de les comprendres de mon mieux, peut être pour mieux les éviter plus tard ;-)

    Par exemple, au niveau de la copie profonde d'un objet à un autre. Est-ce qu'il est possible de faire cela sans pointeur ni new ?

    Si j'ai bien compris, c'est seulement dans le constructeur que la création ne nécessite pas de new, puisqu'un constructeur ne sert qu'à ça. Dans mon exemple, serait-il possible d'appeler le constructeur pour créer de nouveaux éléments au lieu d'utiliser new ?

    encore merci!

  5. #5
    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
    Il faut comprendre que, lorsque tu déclares une variable, tu réserve automatiquement un espace mémoire suffisant pour y placer l'ensemble des données qu'elle contient.

    Le constructeur se contente en somme de faire en sorte que... ta variable soit correctement initialisée et "directement utilisable".

    Ainsi, lorsque tu écrit, tout simplement,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main()
    {
        Couleur c(/*la couleur */);
        Lieu l(/*somewhere*/ );
        Object obj(c, l);
        /*...*/
    }
    tu va créer une variable de type Couleur et nommée c et une autre variable de type Lieu en leur fournissant les valeurs qui les intéressent, puis tu va créer une variable de type Object qui appellera le contsructeur par copie de tes variables c et l pour créer les membres de ton objet Obj.

    Ton objet c et son "comparse" obj.c auront donc les même valeurs, mais seront deux objets totalement différents et indépendant l'un de l'autre (en mémoire).

    Si, de plus, tu définis ta classe ListeObject sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class ListeObject
    {
        public:
            ListeObject(){}
            /* il faut, au minimum, pouvoir rajouter un ojbet à la liste */
            void ajouterObject(Object const & o) /* (1) */
            {
                items_.push_back(o);
            }
        private:
            std::list<Object> items_;
    }
    NOTA: (1)Pour, malgré tout, éviter de nombreuses copies inutiles, on conseille de

    puis que tu continue dans main avec une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main()
    {
        /* c'est la même chose qu'avant ;) */
        Couleur c(/*la couleur */);
        Lieu l(/*somewhere*/ );
        Object obj(c, l);
        ListeObjet liste;
        liste.push_back(obj);
        /*...*/
    }
    il y aura une copie de l'objet obj qui sera créée (et le constructeur par copie de Object appelé) et placée dans le membre items_ de ListeObjet.

    Et, lorsque le constructeur par copie de Object sera appelé, il appellera automatiquement les constructeurs par copie de Couleur et de Lieu...

    Au final, tu as, selon le code, 8 objets différents et totalement indépendants à la fin de main (parce qu'aucun n'a été détruit):
    • Un objet de type ListeObjet nommé liste, qui contient (au travers de son membre items_)
      • Un objet de type Object qui est la copie conforme de obj et qui contient
        • une copie de la copie de l'objet de type Couleur c
        • une copie de la copie de l'objet de type Lieu l
    • L'objet de type Object nommé obj qui contient
      • une copie de l'objet de type Lieu l
      • une copie de l'objet de type Couleur c
    • L'ojbet de type Couleur c
    • l'objet de type Lieu l
    Et tu remarquera que je n'ai jamais utilisé ni un pointeur ni l'opérateur new, simplement, parce que lorsque tu déclares une variable d'un type donné, tu réserve automatiquement un espace mémoire suffisant pour représenter les données qu'elle contient...
    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

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

Discussions similaires

  1. [LG]Tri par insertion dans une liste chainée
    Par mister_dsg dans le forum Langage
    Réponses: 4
    Dernier message: 18/12/2003, 22h34
  2. [LG]suppression dans une liste chainée
    Par mister_dsg dans le forum Langage
    Réponses: 9
    Dernier message: 16/12/2003, 21h20
  3. [langage] Comment rajouter des champs dans une liste
    Par toto_titi dans le forum Langage
    Réponses: 4
    Dernier message: 28/08/2003, 14h09
  4. Réponses: 2
    Dernier message: 17/08/2003, 20h07
  5. Réponses: 4
    Dernier message: 24/04/2003, 22h28

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