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 :

C++ Vecteur d'objets


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2014
    Messages : 8
    Par défaut C++ Vecteur d'objets
    Bonjours à tous !

    J'ai un petit soucis qui me prend la tête depuis un moment et je n'arrive pas à comprendre d'où vient l'erreure

    Alors voilà :
    J'ai une classe Game qui va déclarer un vecteur qui contient une lise de pointeurs sur une autre classe Character

    Dans le fichier game.hpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    vector<Character*> listePersos;

    Dans le fichier game .cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Game::Game(){
        // Ici je crée une entrée  dans la liste
        this->listePersos.push_back(new Character());
     
        //Et la je l'envois à un constructeur d'une autre class
        Menu* menu = new Menu(&this->listePersos);
    }
    Dans le fichier menu.hpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     vector<Character*>* listePersos;
    Dans le fichier menu.cpp

    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
     
    Menu::Menu(vector<Character*>* listePersos){
        this->listePersos = listePersos;
    }
     
    // Plus loin dans une methode de cette classe
    int i;
     
    if (listePersos->size() > 0){
        for (i = 0; i < listePersos->size(); ++i){
            if (listePersos[i]->estControlable()){
                 //Du code
            }
        }
    }
    A la compilation j'obtiens les l'erreur suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    error: base operand of ‘->’ has non-pointer type ‘std::vector<Character*>’
        if (listePersos[i]->estControlable())
                          ^
    j'ai aussi essayé en remplaçant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        if (listePersos[i]->estControlable())
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        if (listePersos[i].estControlable())
    et l'a j'obtiens ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    error: ‘class std::vector<Character*>’ has no member named ‘estControlable’
        if (listePersos[i].estControlable())
                          ^
    J'ai simplifier le code pour vous éviter les paramètres inutiles, si vous avez besoin de plus d'informations n'hésitez pas !

    Merci d'avance et bonne journée

    En fait je ne comprend pas pourquoi il me dit que ‘estControlable’ n'est pas une methode de vector<Character*> alors que je suis sensé faire appel au pointeur Character contenu dedans
    Pire encore sachant que l'attribut listePersos de la classe Menu est un pointeur sur vecteur, de ce fait je comprend encore moins la première erreur de compilations

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Remplaces tout tes :
    Par :
    listePersos est un pointeur, donc *listePersos pour accéder à l'objet qui est un vector, donc (*listePersos)[i] pour accéder à un élément, qui est un pointeur donc (*listePersos)[i]-> pour accéder à un membre.

  3. #3
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 482
    Par défaut
    Et pensez à utiliser des unique_ptr à la place des pointeurs nus.
    http://fr.cppreference.com/w/cpp/memory/unique_ptr

  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,

    La première question que je voudrais poser c'est : pourquoi transmettre ton std::vector<Character *> par pointeur Aurais tu peur qu'il puisse ne pas exister le transmettre par référence (constante pour le fonctions qui n'ont pas vocation à modifier la liste des objets) t'éviterait bien des soucis

    Ensuite, Bacela n'a absolument pas tort : l'utilisation de pointeur intelligents (std::unique_ptr en tête) t'évitera surement quelques cheveux gris avant l'heure

    Enfin, j'ose espérer que tu as pris toutes les précautions nécessaire pour éviter la copie et l'affectation des objets de type Character (et de ses types dérivés)
    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
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2014
    Messages : 8
    Par défaut
    Merci à vous tous pour vos réponse.

    Flob90:listePersos est un pointeur, donc *listePersos pour accéder à l'objet qui est un vector, donc (*listePersos)[i] pour accéder à un élément, qui est un pointeur donc (*listePersos)[i]-> pour accéder à un membre.
    En effet ça fonctionne, mais entre temps j'ai trouvé une solution plus lisible à mes yeux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    listePersos->at(i)->estControlable();
    qui fonctionne tout aussi bien.

    bacelar:
    Et pensez à utiliser des unique_ptr à la place des pointeurs nus.
    http://fr.cppreference.com/w/cpp/memory/unique_ptr
    Je n'avais encore jamais entendu parlé de ce type pointeurs. Mais je me demande si ce là fonctionnerais dans mon cas. (voir la réponse en dessous)

    Enfait pour te répondre koala01.
    J'ai une classe Game qui instancie d'autres classe tels que la fenêtre, le gestionnaire de rendu graphique ect..
    Le problème c'est que pour chaque classe instanciée je dois lui donner un pointeur sur une autre contenue dans Game.
    Par exemple le gestionnaire de rendu à besoin d'un pointeur sur la fenêtre.

    Ou pour cet exemple plus concret,
    la classe Menu (qui gère le menu de sélection ex: la liste des personnages du joueur) à besoin d'un pointeur sur le vecteur listePersos, mais d'autres classes auront aussi besoin de ce vecteur.

    Donc ma question est la suivante, est-il possible qu'une classe B instanciée dans la classe A, puisse accéder aux attributs et méthodes de la classe A ?

    Par contre je n'ai pas bien compris ta dernière question

  6. #6
    Membre émérite

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Billets dans le blog
    1
    Par défaut
    Bonjour,
    Citation Envoyé par ashesClaw Voir le message
    Donc ma question est la suivante, est-il possible qu'une classe B instanciée dans la classe A, puisse accéder aux attributs et méthodes de la classe A ?
    Voici comment faire :

    B.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct A;//Declaration anticipée
    struct B
    {
        B(const A& a);//B prend comme parametre A
        const A& a;//On garde une reference ou un pointeur, const ou non, de la classe A
    };
    B.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "A.h"//On peut inclure A sans problème dans le cpp
    B::B(const A& a) : a(a) 
    { 
        a.foo();
    }
    A.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include "B.h"
    struct A
    {
        A() : b(*this) {}//On initialise B avec ce même A
        const B b;
        void foo() const {}
    };
    Citation Envoyé par ashesClaw Voir le message
    Par contre je n'ai pas bien compris ta dernière question
    Tes classes vont avoir des operateurs de copie et d'affectation mis par défaut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    A a; 
    A a2(a);//affectation
    a = a2;//copie
    Le problème est quand ces classes (entitée) contiennent des pointeurs, les copies ou affectation vont copier les pointeurs mais pas leurs contenus.
    On peut s'assurer que ça n'arrive en ajoutant ces deux lignes à la classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    EntityClassA(EntityClassAconst &) = delete;
    EntityClassA& operator=(const EntityClassA&) = delete;

  7. #7
    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 ashesClaw Voir le message
    Enfait pour te répondre koala01.
    J'ai une classe Game qui instancie d'autres classe tels que la fenêtre, le gestionnaire de rendu graphique ect..
    Le problème c'est que pour chaque classe instanciée je dois lui donner un pointeur sur une autre contenue dans Game.
    Par exemple le gestionnaire de rendu à besoin d'un pointeur sur la fenêtre.
    Mais, la question demeure :pourquoi travailler avec des pointeurs et non avec des réféences, si tu sais que, quoi qu'il arrive, l'objet transmis doit forcément exister
    Ou pour cet exemple plus concret,
    la classe Menu (qui gère le menu de sélection ex: la liste des personnages du joueur) à besoin d'un pointeur sur le vecteur listePersos, mais d'autres classes auront aussi besoin de ce vecteur.
    Encore une fois, pourquoi par pointeur et non par référence

    Bien sur, cela signifie que tu devra initialiser les différents éléments dans un ordre bien précis (il faut que le tableau de Character* existe (sans forcément être remplis, ceci dit) avant de créer ton menu), mais les références sont là pour te simplifier la vie... profites-en

    Donc ma question est la suivante, est-il possible qu'une classe B instanciée dans la classe A, puisse accéder aux attributs et méthodes de la classe A ?
    Lorsque tu appelles le constructeur de ta classe B, il n'y a absolument rien qui t'empêche de lui fournir un des membres de la classe A comme paramètre

    Notes juste que, si tu décides de maintenir la référence vers le membre de la classe A dans la classe B sous la forme d'une référence, tu devras (obligatoirement) passer par les listes d'initialisation car une référence doit être définie lorsqu'elle est créée / déclarée. Mais comme les listes d'initialisation sont la bonne manière de travailler, tu fais d'une pierre deux coups
    Par contre je n'ai pas bien compris ta dernière question
    Typiquement, les classes qui ont sémantique d'entité devraient être non copiable et non affectables afin de garantir l'"unicité référentielle" de chaque objet (comprend: tu ne peux jamais, à un instant T de ton programme, plusieurs instances d'une classe présentant exactement les mêmes valeurs car tu dois pouvoir identifier chacune des instances de manière unique et non ambigüe). Ta classe Character entre très clairement dans cette catégorie et devrait donc en respecter les règles (voir l'entrée suivant le dernier lien donné pour savoir comment faire si tu ne peux pas utiliser C++11 ou supérieur )
    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

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par ashesClaw Voir le message
    En effet ça fonctionne, mais entre temps j'ai trouvé une solution plus lisible à mes yeux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    listePersos->at(i)->estControlable();
    qui fonctionne tout aussi bien.
    C'est pas tout à fait identique à l'opérateur[], y'a des tests faits en plus et une exception générée en cas d'out-of-bound.
    La syntaxe identique serait listePersos->operator[](i)->estControlable(); ou, plus claire : (*listePersos)[i]->estControlable(); comme donné par Koala.

    Citation Envoyé par ashesClaw Voir le message
    J'ai une classe Game qui instancie d'autres classe tels que la fenêtre, le gestionnaire de rendu graphique ect..
    Le problème c'est que pour chaque classe instanciée je dois lui donner un pointeur sur une autre contenue dans Game.
    Par exemple le gestionnaire de rendu à besoin d'un pointeur sur la fenêtre.
    Ta conception n'est pas terrible, tu prends la chose à l'envers amha.
    Généralement c'est l'appli qui ouvre la fenêtre et initialise un Game avec celle-ci. Game instancie tous les éléments nécessaires (soundmanager, network manager, renderer, ....). Ou bien initialisé à côté (le renderer par exemple, ne dépend pas de Game, pas plus que la fenêtre).
    Et tu as un accesseur global typiquement GetGame() accessible.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. Réponses: 10
    Dernier message: 22/09/2008, 10h23
  2. Probleme vecteur d'objet changeant tout seul
    Par mathildeclair dans le forum C++
    Réponses: 6
    Dernier message: 22/05/2008, 17h26
  3. Vecteur d'objets et methodes
    Par edenyorke dans le forum Langage
    Réponses: 7
    Dernier message: 02/05/2007, 13h24
  4. Vecteur d' objets
    Par Mookie dans le forum Langage
    Réponses: 4
    Dernier message: 30/09/2006, 19h00
  5. [MFC] Manipuler un vecteur d'objets
    Par Yellowmat dans le forum MFC
    Réponses: 4
    Dernier message: 13/07/2005, 14h37

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