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 :

Petit problème de vector


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Février 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 5
    Par défaut Petit problème de vector
    Bonsoir,

    Alors, depuis hier, j'ai fait un sous-moteur à la lib SFML.
    Sauf que je voudrais utiliser une liste (array sans limite) de type DrawUnit, qui est une class contenant une fonction drawOnTheWindow pour le moment.
    Et j'ai une belle erreur de la part de Visual ... Donc si quelqu'un peux m'éclairer

    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
    25
    26
     
     
    #ifndef DEF_DRAWCLASS
    #define DEF_DRAWCLASS
     
    #include <SFML/Graphics.hpp>
    #include <vector> 
     
    #include "DrawUnit.h"
     
    using namespace sf;
     
    class DrawClass
    {
    private:
    	std::vector<DrawUnit*> liste_to_draw;
    public:
    	DrawClass();
    	~DrawClass();
     
    	void drawAll(RenderWindow* window);
    	int add_elem(DrawUnit* toAdd);
    	void remove_elem(int index);
    };
     
    #endif
    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
    25
    26
    27
    28
    29
    30
     
     
    #include "DrawClass.h"
    DrawClass::DrawClass()
    {
     
    }
    DrawClass::~DrawClass()
    {
     
    }
     
    void DrawClass::drawAll(RenderWindow* window)
    {
    	int i = 0;
    	for (i = 0; i < (int)liste_to_draw.capacity(); i++)
    	{
    		liste_to_draw[i]->drawOnTheWindow();//Erreur ici
    	}
     
    }
    int DrawClass::add_elem(DrawUnit* toAdd)
    {
    	liste_to_draw.push_back(toAdd);
    	return liste_to_draw.end() - liste_to_draw.begin();
    }
    void DrawClass::remove_elem(int index)
    {
    	liste_to_draw.erase(liste_to_draw.begin() + index);
    }
    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
     
    #ifndef DEF_DRAWUNIT
    #define DEF_DRAWUNIT
     
    #include <SFML/Graphics.hpp>
     
    using namespace sf;
     
    class DrawUnit
    {
    private:
     
    public :
    	int drawOnTheWindow();//RenderWindow* window);
    };
     
    #endif
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    #include "DrawUnit.h"
    int drawOnTheWindow()//(RenderWindow* window)
    {
    	//window->clear();
    	return 0;
    }
    L'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Error	1	error LNK2019: unresolved external symbol "public: int __thiscall DrawUnit::drawOnTheWindow(void)" (?drawOnTheWindow@DrawUnit@@QAEHXZ) referenced in function "public: void __thiscall DrawClass::drawAll(class sf::RenderWindow *)" (?drawAll@DrawClass@@QAEXPAVRenderWindow@sf@@@Z)	C:\Users\Nico\Documents\Visual Studio 2010\Projects\SFML\SFML\DrawClass.obj	SFML
    ps : ça serais simpa aussi de dire s'il y a des trucs fais "bizarrement" car je passe du vb.net au C++, ça change ..

    Merci

  2. #2
    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,

    L'erreur te dit que l'éditeur de liens ne trouve pas le code binaire correspondant à DrawUnit::drawOnTheWindow().

    Selon moi, il y a trois solutions:
    1. Soit VisualStudio s'est "emmêlé les pinceaux" et n'a pas recompilé DrawUnit.cpp après que tu aies changé le prototype de drawOnTheWindow
    2. Soit tu as modifié le prototype de drawOnTheWindow dans le DrawUnit.h mais pas dans DrawUnit.cpp
    3. Soit, enfin, DrawUnit.cpp ne fait pas partie du projet

    Dans le premier cas, je te conseillerais de faire un "clear" de ton projet et de tout recompiler

    Dans le deuxième cas, il faut corriger soit DrawUnit.h soit DrawUnit.cpp pour que les prototypes correspondent (et de préférence faire un clear du projet avant de tout recompiler )

    Dans le troisième cas, il faut veiller à rajouter le fichier manquant à ton projet, avant de compiler à nouveau

    Enfin, si tu es face à un projet important qui serait subdivisé en plusieurs "sous projet" et que DrawUnit.h / DrawUnit.cpp font partie d'un sous projet particulier, il serait bon de commencer par faire pareil avec le sous projet en question
    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

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Février 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 5
    Par défaut
    Okk, Merci.

    J'essaye tout ça demain et je vous redis quoi.

    édit :

    Et sinon le code reste "propre" ?

  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
    Ouppsss...

    En relisant le code, je viens de trouver l'erreur...

    Tu as défini
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int drawOnTheWindow()//(RenderWindow* window)
    {
    	//window->clear();
    	return 0;
    }
    qui défini une fonction libre nommée DrawOnTheWindow...

    Or, tu déclare une fonction membre de la classe DrawUnit qui porte ce nom.

    comme je présumes que tu souhaites effectivement qu'il s'agisse d'une fonction membre de ta classe, la définition devrait être pleinement qualifiée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int DrawUnit::drawOnTheWindow()//(RenderWindow* window)
    {
    	//window->clear();
    	return 0;
    }
    Citation Envoyé par Nicogo Voir le message
    Okk, Merci.

    Et sinon le code reste "propre" ?
    Ben, à moins que la durée de vie de tes objet de type DrawUnit ne soit "gérée par ailleurs", tu risque d'avoir une belle fuite mémoire lors de la destruction de ton objet de type DrawClass.

    Ce que tu places dans ta liste, c'est des pointeurs, qui correspondront de toutes évidences à des objets pour lesquels tu as eu recours à l'allocation dynamique.

    Tu as donc accepté "de facto" de prendre seul la responsabilité de déterminer quand ces objets seront détruits.

    Lorsque la liste sera détruite, tu perdra "toute référence" vers les objets qu'elle contient, et tu ne pourras donc plus y accéder pour détruire correctement les éléments pointés.

    Je te laisses le soin de réfléchir à la manière de résoudre ce problème
    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 chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Royaume-Uni

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par défaut
    Citation Envoyé par Nicogo Voir le message
    Et sinon le code reste "propre" ?
    Non, tu as un bug ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void DrawClass::drawAll(RenderWindow* window)
    {
    	int i = 0;
    	for (i = 0; i < (int)liste_to_draw.capacity(); i++)
    	{
    		liste_to_draw[i]->drawOnTheWindow();//Erreur ici
    	}
     
    }
    std::vector::capacity() te donne le nombre maximum d'éléments que peux contenir ton std::vector avant qu'il ait besoin de ré-allouer de la mémoire. Toi tu veux plutôt le nombre total d'éléments qui sont stockés, et pour ça il faut utiliser std::vector::size().

    Petite remarque en passant sur la boucle, tu peux écrire plus simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int i = 0; i < (int)liste_to_draw.size(); i++)
    Mais il est plus correct d'utiliser une variable non signée pour l'itération, en particulier std::size_t. D'une part ça t'évite le warning que Visual doit t'envoyer parce que tu compares une grandeur signée i et une grandeur non signée std::vector::capacity(), et d'autre part c'est plus correct car i n'a aucune raison d'être négatif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (std::size_t i = 0; i < liste_to_draw.size(); i++)
    Sinon tu peux utiliser les itérateurs. La notation est un peu lourde, mais parfois plus pratique car la majorité des méthodes de std::vector (ou encore certaines fonctions de la bibliothèque standard) travaillent sur des itérateurs. Ici ça n'a pratiquement aucun intérêt, si ce n'est qu'il est un peu plus difficile d'écrire une sottise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (std::vector<DrawUnit*>::iterator i = list_to_draw.begin(); i != list_to_draw.end(); ++i)
    {
        (*i)->drawOnTheWindow();
    }
    Et le top du top, si tu peux utiliser le C++11 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (DrawUnit* unit : list_to_draw)
    {
        unit->drawOnTheWindow();
    }

  6. #6
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 293
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    au cas où tu cherches à améliorer ton code, tu devrais remplacer tous tes pointeurs par des références (références constantes dans certains cas). En tout cas, sur le code que tu as posté, je ne vois pas l'utilité des pointeurs, or, comme on dit: "les pointeurs, on ne les utilise que quand on ne peut pas s'en passer".

  7. #7
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Par défaut
    Bonjour,

    Juste une petite remarque, évite d'utiliser "using namespace" dans les fichiers d'entête, ça pourrais poser problème dans d'autres projets.

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Février 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 5
    Par défaut
    Citation Envoyé par r0d Voir le message
    Bonjour,

    au cas où tu cherches à améliorer ton code, tu devrais remplacer tous tes pointeurs par des références (références constantes dans certains cas). En tout cas, sur le code que tu as posté, je ne vois pas l'utilité des pointeurs, or, comme on dit: "les pointeurs, on ne les utilise que quand on ne peut pas s'en passer".
    Déso du double post, mais par curiosité, dans quel(s) cas est-on obliger d'utiliser un pointeur ?

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

Discussions similaires

  1. Réponses: 22
    Dernier message: 14/04/2014, 00h02
  2. [Debutant][Vector]Petit problème de vector
    Par GyZmoO dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 25/05/2006, 10h39
  3. Réponses: 17
    Dernier message: 13/07/2004, 20h37
  4. petit problème premier plan, arrière plan
    Par gros bob dans le forum OpenGL
    Réponses: 4
    Dernier message: 19/04/2004, 12h00
  5. [jointure] Petit problème sur le type de jointure...
    Par SteelBox dans le forum Langage SQL
    Réponses: 13
    Dernier message: 13/02/2004, 18h55

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