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

Langage C++ Discussion :

Assigner une fonction à une classe? Pas simple!


Sujet :

Langage C++

  1. #21
    Membre du Club
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 59
    Points
    59
    Par défaut
    Tes reflexions me travail (en bien) mais j'ai encore du mal avec le principe du "C'est l'objet qui demande sa destruction et non le stage qui demande à l'objet si il peut le détruire." =p

    Pour situer le fonctionnement, les objets sont déclarés sous forme de list de pointeur sur objet, donc j'ai plein de std::list<GameObject *>, je créer les objets via des operateur new.

    En ce moment, lorsque je fais l'opération de suppression des objets, à chaque tour de boucle de jeu, je fais un bon gros "for" pour parcourir toute ma list d'objet, je repère les objets dont la condition de fin de vie est vrai, je "delete" ces objets et je remove leur pointeur de la liste.

    J'utilise une fonction objet qui fais l'operation de test + le delete, puis je la passe dans une fonction "remove_if" pour retirer le pointeur, ça donne 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
    12
    13
    14
    15
    16
    17
    18
    void Stage::Clean(std::list<GameObject *> &list, Game &game)
    {
    	struct test
    	{
    		sf::View &view;
    		test(sf::View &view) : view(view){}
    		bool operator()(GameObject *shot)
    		{
    			bool condition = shot->EOL(view);
    			if(condition)
    			{
    				delete shot;
    			}
    			return condition;
    		}
    	};
    	list.erase(std::remove_if(list.begin(), list.end(), test(game_view)), list.end());
    }

    Donc toi, ce que tu me proposes dans ton post, ça serai plutôt de faire une fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void Stage::Remove(GameObject *object)
    {
    	// On delete l'objet
    	delete object;
    	// On retire le pointeur de la list
    	list.remove(...);
    }
    Et j'appel cette fonction dans la fonction qui recalcule les données de mon objet à chaque tour de boucle

    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
    void GameObject::Calculate()
    {
    	if(EOL()) // On vérifie la condition de fin de vie
    	{
    		// Si fin de vie
    		my_stage->Remove(this); // On efface
    	}
    	else
    	{
    		// Sinon
    		x += speed;	// On effectue les calculs de coordonnées
    		...
    	}
     
    }
    Ce qui me chiffonne, c'est qu'en faisant ça, mon programme ne va pas aimer de choper un delete sur l'objet dont la fonction est en cours d'exécution... As-tu une idée précise en tête, voir un exemple (existant ou non) à me montrer que je puisse appliquer cette idée?

  2. #22
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Spidyy Voir le message
    Pour situer le fonctionnement, les objets sont déclarés sous forme de list de pointeur sur objet, donc j'ai plein de std::list<GameObject *>, je créer les objets via des operateur new.

    En ce moment, lorsque je fais l'opération de suppression des objets, à chaque tour de boucle de jeu, je fais un bon gros "for" pour parcourir toute ma list d'objet, je repère les objets dont la condition de fin de vie est vrai, je "delete" ces objets et je remove leur pointeur de la liste.

    J'utilise une fonction objet qui fais l'operation de test + le delete, puis je la passe dans une fonction "remove_if" pour retirer le pointeur, ça donne 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
    12
    13
    14
    15
    16
    17
    18
    void Stage::Clean(std::list<GameObject *> &list, Game &game)
    {
    	struct test
    	{
    		sf::View &view;
    		test(sf::View &view) : view(view){}
    		bool operator()(GameObject *shot)
    		{
    			bool condition = shot->EOL(view);
    			if(condition)
    			{
    				delete shot;
    			}
    			return condition;
    		}
    	};
    	list.erase(std::remove_if(list.begin(), list.end(), test(game_view)), list.end());
    }
    Oui,j'ai bien compris l'idée dans laquelle tu travailles
    Citation Envoyé par Spidyy Voir le message
    Tes reflexions me travail (en bien) mais j'ai encore du mal avec le principe du "C'est l'objet qui demande sa destruction et non le stage qui demande à l'objet si il peut le détruire." =p
    Le fait est que c'est ton objet qui dispose de toutes les informations lui permettant de savoir s'il est en vie ou pas, et que ces informations mises à jour en fonction des événements qui se rapportent à ton objet...

    Il me semble donc "logique" que ce soit lui qui "décide" à un moment donné de dire "n'en jetez plus, j'ai mon compte", plutôt que de le faire attendre que "quelqu'un" daigne lui poser la question

    L'avantage, c'est que, plutôt d'avoir un test imbriqué dans une boucle qui est elle-même imbriquée dans une autre boucle en vue de trouver un hypotétique objet à détruire, tu détruit systématiquement les objets au moment où ils remarquent qu'ils sont morts
    Donc toi, ce que tu me proposes dans ton post, ça serai plutôt de faire une fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void Stage::Remove(GameObject *object)
    {
    	// On delete l'objet
    	delete object;
    	// On retire le pointeur de la list
    	list.remove(...);
    }
    Et j'appel cette fonction dans la fonction qui recalcule les données de mon objet à chaque tour de boucle

    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
    void GameObject::Calculate()
    {
    	if(EOL()) // On vérifie la condition de fin de vie
    	{
    		// Si fin de vie
    		my_stage->Remove(this); // On efface
    	}
    	else
    	{
    		// Sinon
    		x += speed;	// On effectue les calculs de coordonnées
    		...
    	}
     
    }
    Oui, c'est effectivement l'idée
    A vrai dire, ce serait même plutôt proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void GameObject::Calculate()
    {
        /*  tout ce qui doit être calculé */
        x += speed;
        /*...*/
        /* on a fini nos calculs... l'objet est il encore vivant ?? 
         * s'il ne l'est plus, on envoie le signal indiquant qu'il est mort
         */
        if(EOL())
            my_stage->Remove(this);
    Ce qui me chiffonne, c'est qu'en faisant ça, mon programme ne va pas aimer de choper un delete sur l'objet dont la fonction est en cours d'exécution... As-tu une idée précise en tête, voir un exemple (existant ou non) à me montrer que je puisse appliquer cette idée?
    Pourquoi n'aimerait-il pas, et pourquoi y aurait-il une fonction en cours d'exécution

    Tant qu'il n'y a rien à faire après le test (donc, dans ton exemple, après l'accolade fermante du else et dans le mien après l'appel de my_stage->remove() ), la fonction est considérée comme étant finie, et l'objet peut être détruit en toute quiétude
    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. #23
    Membre du Club
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Juin 2006
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Juin 2006
    Messages : 122
    Points : 59
    Points
    59
    Par défaut
    C'est tordu mais pour moi, même si il n'existe plus d'opération à faire après un appel "d'autodestruction", il reste quand même à effectuer le retour de fonction, hors je pensais qu'avec un delete sur l'objet en cours, le programme ne savait plus quand retourner, ni où retourner, d'où bloquage...

    Mais bon jvais tester sque tu m'a dis, ça me mettra les idée en place. J'aurai vraiment pas du dormir pendant mes cours. :]

  4. #24
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Ce qui pourrait poser problème, c'est que tu essaye d'aller tripatouiller dans les membres de l'objet après qu'il ait été détruit...

    Mais autrement, lorsque le processeur rencontre l'appel de la fonction, il empile le pointeur courant et deux trois choses, puis il "saute" vers la fonction appelée, qui fait son travail (ici détruire l'objet), puis le processeur récupère le pointeur courant (qui était bien au chaud dans la pile), pour se rendre compte qu'il est en fin de fonction et qu'il doit donc retourner à la fonction appelante de l'actuelle...

    Où est le 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

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. appliquer une fonction à une fonction
    Par stracoma dans le forum C++
    Réponses: 6
    Dernier message: 20/03/2015, 16h35
  2. une fonction n'attend pas la fin de la précedente
    Par Romalafrite dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 30/01/2007, 15h05
  3. Réponses: 7
    Dernier message: 24/01/2007, 10h01
  4. Assigné une fonction à une touche du clavier
    Par jay1234 dans le forum C++
    Réponses: 5
    Dernier message: 10/10/2006, 22h30
  5. passer en paramettre d'une fonction une fonction
    Par RoM3Ro dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 23/06/2006, 15h54

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