[C/C++] Passer un objet de par lui même

Le côté programmation du développement d'un jeu vidéo.

Passer un objet de par lui même

Messagepar Nieluj » 15 Aoû 2011, 13:37

Bonjour,

J'ai encore une question un peu tordue en relation avec la syntaxe c++ cette fois-ci.

Dans mon projet, je cherche à mettre en place un système d'environnement dans lequel les objets peuvent inter-agirent. J'ai donc une classe Environment dont je créé une instance unique. Cette instance dispose d'objets( le player, les ennemis, la map, etc.. ).

Mais lors de la création des objets, je souhaiterai leur passer en paramètre l'instance de la classe environnement, c'est à dire au sein même de cette instance. Je pourrais ainsi accéder aux informations des autres objets à partir de chacun d'eux pour qu'ils puissent inter-agirent entre eux.

Et donc j'ai testé ceci:

Code: Tout sélectionner
player = new Player( this );


En pensant pouvoir récupérer l'instance de la classe Environment dans Player. Mais ça n'a pas l'air de fonctionner.

Il y a une méthode précise à utiliser pour ce genre de chose en c++ ?

Merci !
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Gavos » 15 Aoû 2011, 13:48

C'est pourtant une manière correcte de faire. Il faudrait juste que tu nous dise précisément ce qui "n'a pas fonctionné".
Gavos
 
Messages: 1089
Inscription: 19 Mar 2005, 13:00

Messagepar Nieluj » 15 Aoû 2011, 14:34

Et bien ceci

Code: Tout sélectionner
Player::Player( Environment* _env )


à pas l'air de lui plaire, ça fout un de ces bazar.

Ce sont des erreurs de ce type:

Code: Tout sélectionner
expected `;' before '*' token


Alors qu'il n'y a rien à signaler en réalité. Et que ça concerne des lignes de code qui marchaient très bien auparavant.

Je vais encore chercher d'où ça peut venir mais c'est de l'ordre du surnaturel :00000025:
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Nieluj » 15 Aoû 2011, 14:36

Y a ça aussi:

Code: Tout sélectionner
Environment.h ISO C++ forbids declaration of `Player' with no type
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar remram44 » 15 Aoû 2011, 14:51

Les erreurs que tu rapportes ressembles à des problèmes de déclarations manquantes. Es-tu sûr de ne pas avoir oublié d'inclure de fichier header ?

Peut-être as-tu une dépendance cyclique qui empêche (à cause des header-guards) l'inclusion d'une déclaration (et il manque la forward-declaration correspondante) ; c'est assez dur à dire sans voir plus de code.
Cordialement, remram44.
Avatar de l’utilisateur
remram44
Hello World, I'm new !
 
Messages: 687
Inscription: 27 Juil 2005, 16:18
Localisation: New York City, NY, USA

Messagepar Nieluj » 15 Aoû 2011, 15:01

Tu dois pas voir tord parce que je viens de modifier des choses à ce sujet...
Ce que tu appelles 'dépendance cyclique' et 'header-guards' ce sont les #ifndef/#endif ?

Je vais voir ça tout de suite.
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Nieluj » 15 Aoû 2011, 15:09

A ce sujet, mieux vaut-il mettre les include après #define CLASS_H ou avant ? C'est ça qui pourrait bloquer la définition de Player ?
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar remram44 » 15 Aoû 2011, 15:15

Les headers guard, c'est en effet le "#ifndef BLA_H #define BLA_H" que tu mets en haut de ton fichier header (et le "#endif" en bas) qui empêche d'inclure plusieurs fois le même fichier.

Pour la dépendance cyclique, je te fais un exemple, tu vas comprendre.
Cordialement, remram44.
Avatar de l’utilisateur
remram44
Hello World, I'm new !
 
Messages: 687
Inscription: 27 Juil 2005, 16:18
Localisation: New York City, NY, USA

Messagepar Nieluj » 15 Aoû 2011, 15:17

Ca a bien l'air d'être le #include "Player.h" qui n'est pas reconnu dans 'Environment' pourtant je n'ai le problème que depuis que j'ai modifié ma classe Environment et Player pour réaliser ce que je décris au début de ce sujet. :00000017: . Je bloque là.

J'ai beau sortir #include "Player.h" du #ifndef, rien n'y fait...
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Nieluj » 15 Aoû 2011, 15:24

Voilà ce que ça donne pour la classe Environment:

Code: Tout sélectionner
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H

#include <fstream>
#include <string>
#include <iostream>
#include <vector>

#include "constante.h"
#include "PhysicObject.h"
#include "IntelligentObject.h"

#include "Map.h"
#include "Player.h"
#include "Monster.h"

//------------------------------------------------------------------------------
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//------------------------------------------------------------------------------
//Classe : Environment
//------------------------------------------------------------------------------
//Definition : Permet de définir un environnement dans lequel peuvent intéragir
//             les éléments:
//             -Map
//             -Player
//             -PhysicObject
//             -IntelligentObject
//             -liste à compléter ...
//------------------------------------------------------------------------------
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//------------------------------------------------------------------------------
class Environment
{
   protected:
                         
    public:
           
        SDL_Surface*                        dest;
        Map*                                map;                                //Objet de type Map
        Player*                             player;
        vector <PhysicObject *>             physxObjects;                       //Contient les occurences de type PhysicObject
        vector <IntelligentObject *>        intelObjects;                       //Contient les occurences de type IntelligentObject
                   
        Environment( SDL_Surface* _destination );
       
};

//***********************************************************************
//Méthode : ENVIRONMENT
//-----------------------------------------------------------------------
//Definition : Constructeur de la classe
//***********************************************************************
Environment::Environment( SDL_Surface* _destination )
{

    this->dest = _destination;
   
    //Creation de la map
    this->map = new Map( this->dest );
       
    //Creation du player
    player = new Player( this );
...

}

Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar remram44 » 15 Aoû 2011, 15:25

Voilà l'exemple, il ressemble un peu à ton cas.

Une class "Class" qui contient des "Truc". Comme elle a besoin de la définition de "Truc", elle inclut "truc.h" :
Code: Tout sélectionner
#ifndef TRUC_H
#define TRUC_H

#include "Class.h"

class Truc {

public:
    Truc(Class *c);

};

#endif


La classe Truc. Comme le constructeur prend un pointeur sur "Class", on inclut "class.h" :
Code: Tout sélectionner
#ifndef TRUC_H
#define TRUC_H

#include "Class.h"

class Truc {

public:
    Truc(Class *c);

};

#endif


Maintenant, prenons une définition au pif (par exemple, class.cpp) :
Code: Tout sélectionner
#include "class.h"

Class::Class()
  : truc1(this), truc2(this)
{
}


Et là, ça ne marche pas :
Code: Tout sélectionner
% g++ -c class.cpp -o class.o
In file included from class.h:4:0,
                 from class.cpp:1:
truc.h:10:16: error: expected ')' before '*' token


Ca ne marche pas parce que :
Quand tu compiles class.cpp, class.h est inclu.
CLASS_H est défini, puis avant d'arriver à la définition de Class, truc.h est inclu.
TRUC_H est défini, puis quand on arrive à la définition de Truc, Class n'a pas encore été défini !

Une solution dans ce cas est de ne pas inclure class.h depuis truc.h mais d'utiliser à la place une forward-declaration :
Code: Tout sélectionner
#ifndef TRUC_H
#define TRUC_H

//#include "Class.h"
class Class; // forward-declaration

class Truc {

public:
    Truc(Class *c);

};

#endif
Cordialement, remram44.
Avatar de l’utilisateur
remram44
Hello World, I'm new !
 
Messages: 687
Inscription: 27 Juil 2005, 16:18
Localisation: New York City, NY, USA

Messagepar remram44 » 15 Aoû 2011, 15:27

Euh... Tu n'es pas censé définir les méthodes de ta classe Environnement dans le header hein, le code a sa place dans un fichier .cpp...
Cordialement, remram44.
Avatar de l’utilisateur
remram44
Hello World, I'm new !
 
Messages: 687
Inscription: 27 Juil 2005, 16:18
Localisation: New York City, NY, USA

Messagepar Nieluj » 15 Aoû 2011, 15:30

Et pour le player :

Code: Tout sélectionner
#ifndef PLAYER_H
#define PLAYER_H

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"

#include "constante.h"

#include "PhysicObject.h"
#include "Environment.h"
#include <math.h>

//------------------------------------------------------------------------------
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//------------------------------------------------------------------------------
//Classe : Player
//------------------------------------------------------------------------------
//Definition :   Modèle de joueur pour un environnement à base de tiles.
//------------------------------------------------------------------------------
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//------------------------------------------------------------------------------
class Player: public PhysicObject
{
   private:
   
    SDL_Rect rectangle;
    //--------------------------------------------------------------------------
    SDL_Surface* image;
    //--------------------------------------------------------------------------
    //SDL_Surface* tilesheet;
    //--------------------------------------------------------------------------
    //SDL_Rect clips[ PLAYER_TILESHEET_WIDTH ][ PLAYER_TILESHEET_HEIGHT ];
    //--------------------------------------------------------------------------
    //int frame;
    //--------------------------------------------------------------------------
    //int action;
    //------------------------------------------------------------------------

    public:
   
    //Player( SDL_Surface* _destination, int** _map );
    Player( Environment* _env );
    void Move( int _action, int _speed );
    void Wait( int _action );
   
      //--------------------------------------------------------------------------
   int walkspeed;
   int runspeed;
   
};

//***********************************************************************
//Méthode : PLAYER
//-----------------------------------------------------------------------
//Definition : Constructeur de la classe
//***********************************************************************
Player::Player( Environment* _env )
{

   ...

}
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Nieluj » 15 Aoû 2011, 15:32

remram44 a écrit:Euh... Tu n'es pas censé définir les méthodes de ta classe Environnement dans le header hein, le code a sa place dans un fichier .cpp...


Tu as tout à fait raison :00000026: , j'ai pas trop d'excuse mais je comptais modifier celà. Ca ne devrait pas poser de problèmes tant que ce ne sont que des tests non ?
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar remram44 » 15 Aoû 2011, 15:43

Nieluj a écrit:Ca ne devrait pas poser de problèmes tant que ce ne sont que des tests non ?


Si, ça va te poser des problèmes. Si tu inclus ce header dans plusieurs fichier-sources, les méthodes qui s'y trouvent vont être compilées plusieurs fois... Même si c'est le même code, une méthode ne peut pas être définie plusieurs fois.

Je pense que tu auras systématiquement une erreur si tu gardes ce système.
Cordialement, remram44.
Avatar de l’utilisateur
remram44
Hello World, I'm new !
 
Messages: 687
Inscription: 27 Juil 2005, 16:18
Localisation: New York City, NY, USA

Messagepar Nieluj » 15 Aoû 2011, 15:46

Bon jusqu'à maintenant je n'avais pas eu de problèmes, du coup je vais suivre tes conseils. Merci pour les explications !
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Nieluj » 15 Aoû 2011, 17:23

Je n'ai toujours pas de solutions.

Code: Tout sélectionner
Compilateur: Default compiler
Building Makefile: "C:\Dev-Cpp\PROJETS\2D Engine - ActionRPG\Makefile.win"
Exécution de  make clean
rm -f main.o PhysicObject.o Player.o Tile.o Timer.o Monster.o IntelligentObject.o Map.o Systeme.o Environment.o Plateforme_private.res Plateforme.exe

g++.exe -D__DEBUG__ -c main.cpp -o main.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"    -g3

In file included from Player.h:12,
                 from Systeme.h:10,
                 from main.cpp:8:
Environment.h:41: error: ISO C++ forbids declaration of `Player' with no type
Environment.h:41: error: expected `;' before '*' token

make.exe: *** [main.o] Error 1

Exécution terminée



Voici, la ligne 41 en question :

Code: Tout sélectionner
Player* player;


Ca ressemble bien à un problème d'inclusion, pourtant les fichiers nécessaires sont bien renseignés :00000020: .
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar Nieluj » 15 Aoû 2011, 18:06

J'avais mal lu ton explication sur les forward declaration, et en effet ça a l'air de fonctionner maintenant. Mais j'ai un nouveau truc ( forcément ):

Code: Tout sélectionner
Player.h multiple types in one declaration


Comme je ne suis pas très à l'aise avec tout ce qui est inclusion je galère pour par grand chose j'imagine.

J'ai 2 erreurs de ce type qui pointent sur 2 fichiers header au niveau de la fermeture de la classe, sur ca en gros:
Code: Tout sélectionner
};


Comme j'ai utilisé la méthode de forward declaration, j'ai ajouté ceci dans le header de Player:

Code: Tout sélectionner
class Environment


Donc je peux comprendre qu'il considère ça comme un autre type pour une seule déclaration d'où l'erreur. Seulement, il me le met également pour un header dans lequel je ne le fais pas...
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11

Messagepar thesus » 15 Aoû 2011, 19:36

class Environnement; (avec le ; à la fin)

il faut le mettre avant le class Player et normalement ça devrait fonctionner.

Sinon j'ai vu que le répertoire est "C:\Dev-Cpp\PROJETS\2D Engine - ActionRPG\Makefile.win" : ne JAMAIS mettre d'espace ni de caractère spéciaux, d'ailleurs si tu est sous CodeBlocks le mode debug ne fonctionnera pas.
Avatar de l’utilisateur
thesus
Hello World, I'm new !
 
Messages: 198
Inscription: 29 Déc 2008, 14:14

Messagepar Nieluj » 15 Aoû 2011, 19:58

Merci, pour votre aide. Ca compile maintenant, je vais pouvoir avancer !
C'était juste un sacré bordel dans mes inclusions, un peu de ménage ça fait du bien :).
Avatar de l’utilisateur
Nieluj
Hello World, I'm new !
 
Messages: 110
Inscription: 27 Oct 2009, 14:11


Retourner vers Programmation

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 12 invités

cron