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 :

Question sur pointer un objet d'un array


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2007
    Messages : 165
    Par défaut Question sur pointer un objet d'un array
    Bonjour,

    Voici ce que j'ai :
    Une struct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    struct Sprite
    	{
    		string name;
    		LPDIRECT3DTEXTURE9* texture;
    		int currentFrame, startFrame, endFrame;
    		int startTime, delay, direction, columns;
    	};
    Un dynamic array qui en contient plusieurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<Sprite> m_spritesStruct
    Et un dynamic array qui contient des textures
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<LPDIRECT3DTEXTURE9> m_textures;
    Est-il possible qu'un pointeur d'une struct qui est dans le array m_spritesStruct pointe sur une texture qui est dans l'array m_textures ?

    Je demande cela car le pointeur de la struct marche mais dès que je place l'objet struct dans le array le pointeur ne marche plus.

    Cordialement,

    rXp>!<

  2. #2
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 59
    Par défaut
    Salut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	m_spritesStruct[i].texture = &m_textures[j];
    ou alors j'ai pas tout saisi..

    Cdt

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2007
    Messages : 165
    Par défaut
    Citation Envoyé par kessoufi Voir le message
    Salut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	m_spritesStruct[i].texture = &m_textures[j];
    ou alors j'ai pas tout saisi..

    Cdt
    Alors je vous montre le 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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    void SpriteHelper::CreateSprite(string path, string name, int startFrame, int endFrame, int direction, int columns, int delay)
    {
    	bool exist = false;
    	vector<Sprite>::iterator it;
            //see if the struct already exist
    	for(it = m_spritesStruct.begin();it<m_spritesStruct.end();it++)
    	{
    		Sprite s = *it;
    		if(s.name == name)
    		{
    			exist = true;
    		}
    	}
     
            //if not we create a new sprite struct
    	if(!exist)
    	{
    			Sprite sprite;
    			sprite.name = name;
    			sprite.currentFrame = -1;
    			sprite.direction = direction;
    			sprite.columns = columns;
    			sprite.endFrame = endFrame;
    			sprite.startFrame = startFrame;
    			sprite.delay = delay;
     
    			int i = 0;
    			vector<string>::iterator it;
                            //look through the name list to find if the texture is loaded
    			for(it = m_texturesName.begin();it<m_texturesName.end();it++)
    			{
    				string str = *it;
                                    //if it is
    				if(str == path)
    				{
                                            //set the texture pointer to the struct
    					sprite.texture = &m_textures.at(i);
    				}
    				i++;
    			}
                            //add the struct to the array
    			m_spritesStruct.push_back(sprite);
    	}
    }
    Voici le code de la méthode. Donc sprite.texture n'a aucun problème mais si je regarde dans le m_spritesStruct une fois le sprite ajouté, je vois que le sprite à des problèmes de pointer.

  4. #4
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 59
    Par défaut
    est ce que par hasard le destructeur de Sprite (s'il y'en a) libère la texture ?

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2007
    Messages : 165
    Par défaut
    Citation Envoyé par kessoufi Voir le message
    est ce que par hasard le destructeur de Sprite (s'il y'en a) libère la texture ?
    Non, tout se fait dans le destructeur de la classe en question et non dans la structure.

  6. #6
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 59
    Par défaut
    Donc si je comprends bien, après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_spritesStruct.push_back(sprite);
    cet assert échoue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    assert(sprite.texture == m_spriteStruct[m_spriteStruct.size() -1].texture);
    sinon à partir de quelle ligne ça échoue ?

  7. #7
    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
    Par défaut
    Salut,
    D'un point de vue design, je te déconseille fortement de stocker un pointeur - tout comme un itérateur (car c'est sensiblement la même chose) - d'un élément du std::vector. La raison en est simple : beaucoup d'opérations de std::vector ne te garantissent pas une préservation des itérateurs & pointeurs.
    C'est probablement ce qui explique ton problème.

  8. #8
    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
    Par défaut
    SVP : pensez STL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	for(it = m_spritesStruct.begin();it<m_spritesStruct.end();it++)
    	{
    		Sprite s = *it;
    		if(s.name == name)
    		{
    			exist = true;
    		}
    	}
    c'est jamais qu'un std::find_if !!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    auto const it = std::find_if(spritesStruct.begin(),spritesStruct.end(),[&name](Sprite const &s_){return s.name==name;});
    const bool exists = (it != spritesStruct.end());
    Le prédicat est en lambda mais ça marche très bien avec du boost.lambda ou un simple foncteur maison si besoin en C++98.

    *************
    Idem pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    			for(it = m_texturesName.begin();it<m_texturesName.end();it++)
    			{
    				string str = *it;
                                    //if it is
    				if(str == path)
    				{
                                            //set the texture pointer to the struct
    					sprite.texture = &m_textures.at(i);
    				}
    				i++;
    			}
    qui doit pouvoir être quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    auto it = std::find_if(m_texturesName.begin(),m_texturesName.end(),[&path](std::string const &s_){return s_==path;});
    if(it!=m_texturesName.end())
    {
       index = std::distance(m_texturesName.begin(),it);
    }

    *************
    L'utilisation des algorithmes standards (ou des siens) n'est pas un maniérisme : en terme de lecture de code, je comprends tout de suite ce qu'a voulu faire le codeur lorsque je lis std::find_if alors qu'une boucle for demande à être analysée avant de comprendre son objectif/utilité (et encore, à condition qu'elle ne contienne pas un bug).

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2007
    Messages : 165
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    SVP : pensez STL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	for(it = m_spritesStruct.begin();it<m_spritesStruct.end();it++)
    	{
    		Sprite s = *it;
    		if(s.name == name)
    		{
    			exist = true;
    		}
    	}
    c'est jamais qu'un std::find_if !!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    auto const it = std::find_if(spritesStruct.begin(),spritesStruct.end(),[&name](Sprite const &s_){return s.name==name;});
    const bool exists = (it != spritesStruct.end());
    Le prédicat est en lambda mais ça marche très bien avec du boost.lambda ou un simple foncteur maison si besoin en C++98.

    *************
    Idem pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    			for(it = m_texturesName.begin();it<m_texturesName.end();it++)
    			{
    				string str = *it;
                                    //if it is
    				if(str == path)
    				{
                                            //set the texture pointer to the struct
    					sprite.texture = &m_textures.at(i);
    				}
    				i++;
    			}
    qui doit pouvoir être quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    auto it = std::find_if(m_texturesName.begin(),m_texturesName.end(),[&path](std::string const &s_){return s_==path;});
    if(it!=m_texturesName.end())
    {
       index = std::distance(m_texturesName.begin(),it);
    }

    *************
    L'utilisation des algorithmes standards (ou des siens) n'est pas un maniérisme : en terme de lecture de code, je comprends tout de suite ce qu'a voulu faire le codeur lorsque je lis std::find_if alors qu'une boucle for demande à être analysée avant de comprendre son objectif/utilité (et encore, à condition qu'elle ne contienne pas un bug).
    Je retiens tout cela, et je débute en C++ je ne connais pas encore tout vu que je viens de java.

    Ensuite si c'est déconseillé de stocker des pointeur dois-je stocker la texture 2 fois ? C'est pas une perte de mémoire considérable à la longue ?

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Citation Envoyé par rXpCH Voir le message
    Ensuite si c'est déconseillé de stocker des pointeur dois-je stocker la texture 2 fois ? C'est pas une perte de mémoire considérable à la longue ?
    Non, car tu peux stocker des pointeurs dans le vecteur de textures ! Tu peux même stocker des shared_pointer dans le vecteur et la structure, ça te simplifiera encore plus la vie.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2007
    Messages : 165
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Non, car tu peux stocker des pointeurs dans le vecteur de textures ! Tu peux même stocker des shared_pointer dans le vecteur et la structure, ça te simplifiera encore plus la vie.
    Donc si j'ai bien compris, stocker des pointeurs dans des vecteur c'est déconseillé mais stocker des shared_pointer dans des vecteurs c'est ok ?
    Je ne connaissais pas ce genre de pointeurs donc je me suis renseigné rapidement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    shared_ptr<int> p(new int(2));
    Cela ressemble beaucoup à un vecteur non ? Donc au lieu de mettre mes pointeurs, je devrais mettre des shared_pointer à la place et le problème serait résolu ?

  12. #12
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Citation Envoyé par rXpCH Voir le message
    Donc si j'ai bien compris, stocker des pointeurs dans des vecteur c'est déconseillé mais stocker des shared_pointer dans des vecteurs c'est ok ?
    Je ne connaissais pas ce genre de pointeurs donc je me suis renseigné rapidement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    shared_ptr<int> p(new int(2));
    Cela ressemble beaucoup à un vecteur non ? Donc au lieu de mettre mes pointeurs, je devrais mettre des shared_pointer à la place et le problème serait résolu ?
    Heu non c'est pas tout à fait ça . Ce qui est déconseillé, c'est de stocker un pointeur qui pointe vers un élément d'un vector. Par contre, tu peux très bien stocker un pointeur dans le vecteur, pour peu que tu gères ta mémoire correctement !

    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct Sprite
    	{
    		string name;
    		LPDIRECT3DTEXTURE9* texture;
    		int currentFrame, startFrame, endFrame;
    		int startTime, delay, direction, columns;
    	};
     
    ...
    std::vector<LPDIRECT3DTEXTURE9*> m_textures; // Vector de textures
    ...

    Citation Envoyé par rXpCH Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    shared_ptr<int> p(new int(2));
    Cela ressemble beaucoup à un vecteur non ? Donc au lieu de mettre mes pointeurs, je devrais mettre des shared_pointer à la place et le problème serait résolu ?
    Ne t'y méprend pas : shared_ptr t'aide à gérer un pointeur, en aucun cas un vecteur ou une suite d'éléments !

    Tu pourrais ainsi utiliser quelque chose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct Sprite
    	{
    		string name;
    		shared_ptr<LPDIRECT3DTEXTURE9> texture;
    		int currentFrame, startFrame, endFrame;
    		int startTime, delay, direction, columns;
    	};
     
    ...
    std::vector< shared_ptr<LPDIRECT3DTEXTURE9> > m_textures; // Vector de textures
    ...
    Ce n'est en rien une obligation, mais ce qui est important, c'est d'être homogène et robuste dans la manière de pointer les textures, ce qui n'est pas le cas dans le code que tu nous as montré.

  13. #13
    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
    Par défaut
    LPDIRECT3DTEXTURE9 est déjà un pointeur. Inutile d'en ajouter un nouveau, je pense. L'accès en temps constant de la texture à partir du sprite est-il nécessaire ? Car peut être stocker le nom de la texture (ou un hash) dans le sprite et ensuite faire le lien avec un pointeur/indice/iterateur adéquat via un conteneur associatif fortement couplé au std::vector (si vraiment besoin d'un vecteur sinon directement le conteneur associatif).

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2007
    Messages : 165
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Ce n'est en rien une obligation, mais ce qui est important, c'est d'être homogène et robuste dans la manière de pointer les textures, ce qui n'est pas le cas dans le code que tu nous as montré.
    Tout d'abord merci ! J'ai remplacé mes pointeurs, j'ai changé mes boucles for en find_if et donc par la même occasion appris 2 ou 3 trucs dans le monde du c++.

    Ensuite pour 3DArchi, alors je suis conscient que LPDIRECT3DTEXTURE9 est le pointeur de IDDIRECT3DTEXTURE9.
    Maintenant que le code fonctionne je vais essayé d'optimiser cela et donc de pas pointer des pointeur mais d'employé directement un vecteur de LP...
    Ensuite dans sprite je pourrais mettre que le nom ou un hash, mais ce ne serait pas une perte de temps d'itérer la liste à chaque recherche de texture ?

    Merci encore une fois de vos réponses

    Cordialement,

    rXp>!<

  15. #15
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    LPDIRECT3DTEXTURE9 est déjà un pointeur. Inutile d'en ajouter un nouveau, je pense..
    Absolument ! Je m'étais complètement abstrait de la nature du type en question.

Discussions similaires

  1. question sur la gestion objet GTK
    Par Christophe dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 16/09/2011, 13h54
  2. Question sur la prog objet avec R, S4
    Par Hydro999 dans le forum R
    Réponses: 4
    Dernier message: 10/11/2010, 11h44
  3. [FLASH 8] Question sur la portée des objets.
    Par i_shinji dans le forum Flash
    Réponses: 1
    Dernier message: 02/11/2005, 17h18
  4. Questions sur la programmation objet en Delphi
    Par Manopower dans le forum Débuter
    Réponses: 20
    Dernier message: 15/06/2005, 15h39
  5. Réponses: 2
    Dernier message: 17/03/2004, 13h58

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