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 :

créer objets attributs d'une classe en nombre inconnu


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut créer objets attributs d'une classe en nombre inconnu
    Bonjour,

    j'ai affaire à une classe qui doit comporter en attribut des objets d'une autre classe, ou des pointeurs sur ces objets, mais dont le nombre est inconnu au moment où on lance la méthode (ce nombre est lu dans un fichier). J'ai utilisé le mot clé new pour créer dynamiquement le nombre d'objets requis, mais est-il possible de faire autrement?

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Le type d'objet qui stocke une quantité variable d'objets s'appelle std::vector ce type est un des premiers que l'on apprends alors que l'utilisation de l'opérateur new est réservée aux experts. Ton cours de C++ est vraiment bizarre!

  3. #3
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Bonjour,

    Le type d'objet qui stocke une quantité variable d'objets s'appelle std::vector ce type est un des premiers que l'on apprends alors que l'utilisation de l'opérateur new est réservée aux experts. Ton cours de C++ est vraiment bizarre!
    Salut.
    Je connais vector, mais ça n'a pas de rapport avec la problèmatique. Comme on me l'a déjà fait remarquer à juste titre, le mieux est de poster du code. Je ne l'ai pas sous la main dans l'immédiat mais je reviendrai.

  4. #4
    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,
    Citation Envoyé par Chezkele Voir le message
    Salut.
    Je connais vector, mais ça n'a pas de rapport avec la problèmatique.
    Et pourtant si, std::vector a bel et bien un rapport avec la problématique, même s'il n'est pas ** forcément ** évident au premier abord.

    Car toutes les collections de la bibliothèque standard qui permettent de gérer leur taille à l'exécution -- comprend qui peuvent contenir un nombre variable et défini à l'exécution d'élément -- ce qui correspond, en gros, à toutes les collections de la bibliothèque standard à l'exception de std::array, permettent depuis toujours d'ajouter la copie d'un élément existant, qui, contrairement à l'élément "original" (dont la durée de vie est généralement limitée) "survivra" aussi longtemps que la collection elle-même existe.

    De plus, toutes les collections concernées disposent depuis 2011 (cela fait quand même 11 ans, presque 12, il est donc largement temps de s'en rendre compte ) de la possibilité de créer "sur place" un nouvel élément qui sera ajouté à la collection sans avoir besoin d'être copié.

    Dans un cas comme dans l'autre, on peut donc effectivement dire que, quoi qu'il arrive, le simple fait de pouvoir maintenir "un nombre d'éléments qui n'est connu qu'à l'exécution" (par exemple, lorsqu'on lit un fichier) implique forcément la possibilité de créer ces éléments
    Avant 2011, nous aurions suivi une logique qui aurait été proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    On crée la collection qui nous convient (un std::vector, par exemple)
    TANT QUE (l'on arrive à extraire les données qui nous permettent de créer un élément)
        on crée l'élément à partir des données extraites
        on copie l'élément dans la collection
    FIN TANT
    on dispose ici d'un nombre d'éléments identique à celui dont on a pu extraire les données du fichier
    Depuis 2011, nous pouvons un tout petit peu modifier cette logique pour lui donner une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    On crée la collection qui nous convient (un std::vector, par exemple)
    TANT QUE (l'on arrive à extraire les données qui nous permettent de créer un élément)
        on crée "sur place" dans la collection un élément à partir des données extraites
    FIN TANT
    on dispose ici d'un nombre d'éléments identique à celui dont on a pu extraire les données du fichier
    Maintenant, il y a quand même deux questions à se poser: La première est de savoir si les attributs de ta classe peuvent être copiés.

    Ce sera le cas si les attributs en question on ce que l'on appelle une "sémantique de valeur".

    Si la réponse est positive, la deuxième question n'a plus vraiment de sens, car elle s'applique essentiellement au attributs qui ne s'accommoderaient pas de voir des copies d'eux-même se balader à gauche et à droite (du fait de ce que l'on appelle "par opposition" une "sémantique d'entité", dont l'un des point essentiels est de faire partie d'une hiérarchie de classes suite à une relation d'héritage).

    Dans ce cas, il faut en effet se poser la question de savoir "qui" sera effectivement le mieux placé pour prendre la décision de détruire un élément de la collection lorsque celui-ci devient inutile (on parle généralement de la propriété de l'élément concerné, au sens "de la responsabilité de maintenir cet élément en mémoire").

    Les réponses à ces questions dépendant exclusivement de la situation dans laquelle tu te trouves dans le cadre de ton projet, il t'appartient, et à toi seul, de les apporter. En fonction de celles-ci, les explications pourront se poursuivre
    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

  5. #5
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 532
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 532
    Par défaut
    Citation Envoyé par Chezkele Voir le message
    J'ai utilisé le mot clé new pour créer dynamiquement le nombre d'objets requis, mais est-il possible de faire autrement?
    si je comprends bien vous voulez compter le nombre de fois où une instance de classe est crée ?
    Si c'est le cas oui on peut utiliser un conteneur comme std::vector et la méthode size retournera le nombre d'instances.

  6. #6
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut
    Merci pour vos réponse, et en particulier à koala01 qui m'a peut-être donné un bille improtante.
    J'ai mis les pointeurs sur les fameux objets dans un map. Mon problème n'est pas que je ne connais pas les collections (mais peut-être pas assez bien la façon de s'en servir. ).
    En parcourant le forum, j'ai vu le code d'un gars qui a fait un peu la même chose que moi. Il a une classe Game qui va déclarer un vecteur qui contient une liste de pointeurs sur une autre classe Character. Son code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    vector<Character*> listePersos;
     
    (...)
     
    Game::Game(){
       // Ici je crée une entrée  dans la liste
       this->listePersos.push_back(new Character());
    }
    Est-il possible de procéder autrement qu'en utilisant le mot clé new?

  7. #7
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut
    Ok, je pense que j'ai la réponse dans le fil suivant:
    https://www.developpez.net/forums/d1...objets-boucle/

    Ca devrait le faire, je ne sais pas trop pourquoi je me suis pris la tête comme ça avec new.

  8. #8
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 532
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 532
    Par défaut
    Citation Envoyé par Chezkele Voir le message
    Est-il possible de procéder autrement qu'en utilisant le mot clé new?
    bonsoir si le conteneur ne contient pas de pointeurs pas besoin; déclarer simplement std::vector<character> characters
    Par contre si on empile des pointeurs oui allouer avec new et bien faire les delete correspondants.

  9. #9
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut
    Citation Envoyé par Mat.M
    Par contre si on empile des pointeurs oui allouer avec new et bien faire les delete correspondants.
    Créer l'objet, puis insérer dans le vecteur son adresse avec & n'est pas possible?

  10. #10
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Citation Envoyé par Chezkele Voir le message
    Créer l'objet, puis insérer dans le vecteur son adresse avec & n'est pas possible?
    C'est possible dans de rares cas, mais c'est extrêmement complexe.
    Si tu crées l'objet, et que tu garantis (au présent et y compris les évolutions futures) que l'objet créé persistera au moins aussi longtemps que ton std::vector<>, mémoriser l'adresse de cet objet fonctionnera.
    Mais si l'objet n'est pas persistant (est un temporaire, est une variable locale, est dans une collection persistante mais qui pourrait avoir ses itérateurs invalidés, ...) alors conserver l'adresse ne peut pas fonctionner.

    Le moyen le plus sûr est de stocker des std::unique_ptr<> dans le std::vector<>, car alors le std::vector<> devient le propriétaire des objets et on a la garantie que les pointeurs qu'il contient seront toujours valides.
    Mais si tu es sûr de la persistance des objets (le cas rare), il est surement plus "lisible" de stocker dans ton std::vector<> des std::reference_wrapper<> de ton objet plutôt que des pointeurs.
    Mémoriser des pointeurs est une très mauvaise idée.

Discussions similaires

  1. Passer un objet comme attribut d'une classe
    Par Leduc08 dans le forum Ext JS / Sencha
    Réponses: 1
    Dernier message: 05/04/2011, 11h54
  2. Réponses: 10
    Dernier message: 25/05/2010, 14h25
  3. Réponses: 14
    Dernier message: 07/03/2010, 20h08
  4. Récupérer le nombre et le type d'attribut d'une class
    Par adurandet dans le forum Langage
    Réponses: 5
    Dernier message: 27/11/2009, 18h19
  5. Créer une liste d'objets statiques dans une classe
    Par crossbowman dans le forum C++
    Réponses: 3
    Dernier message: 13/03/2006, 09h11

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