[C++] Problème en POO

Tijee Messages postés 11 Date d'inscription mardi 6 avril 2004 Statut Membre Dernière intervention 22 juillet 2004 - 6 juil. 2004 à 18:51
Tijee Messages postés 11 Date d'inscription mardi 6 avril 2004 Statut Membre Dernière intervention 22 juillet 2004 - 7 juil. 2004 à 09:46
Bonjour à tous.
Voila, j'ai fait un petit moteur 2D avec SDL compilé avec Dev-Cpp, il est simple mais fonctionne très bien. J'aimerais parvenir au même résultat mais en POO et pour l'instant je me noie !
Voici mon code, j'espère qu'il n'est pas trop rébarbatif, en tous cas il est assez long !

fichier main.cpp

#include "declarations.h"

int main(int argc, char* argv[])
{
Initialiser();
AttendreEvenements();
Afficher();
}

fichier initialisation.cpp :

#include "declarations.h"

void Initialiser()
{
// Initialisation de la SDL
SDL_Init(SDL_INIT_VIDEO);
SDL_EnableKeyRepeat(1,150);
atexit(SDL_Quit);

// Position initiale de la caméra (coin haut-gauche)
XCamera = (LARGMAP/2) - (LARGECRAN/(2*LARGOBJET));
YCamera = (HAUTMAP/2) - (HAUTECRAN/(2*HAUTOBJET));

// Initialisation des surfaces à charger
Ecran = SDL_SetVideoMode(LARGECRAN,HAUTECRAN,16,SDL_SWSURFACE |
SDL_DOUBLEBUF | SDL_FULLSCREEN);
Objet Arbre1("./arbre.bmp",20,20);
Objet Arbre2("./arbre.bmp",15,25);

// Création de la fenêtre
SDL_WM_SetCaption(NULL,NULL);
}

fichier evenements.cpp :

#include "declarations.h"

void AttendreEvenements()
{
while(1) // Boucle de jeu
{
SDL_Event Event;
if(SDL_PollEvent(&Event) && Event.type == SDL_KEYDOWN)
{
if(Event.key.state == SDL_PRESSED)
{
switch(Event.key.keysym.sym)
{
case SDLK_ESCAPE : exit(1); break;
}
}
}
Afficher();
}
}

fichier afficher.cpp :

#include "declarations.h"

void Afficher()
{
// On parcourt la liste chaînée
Objet *pCurrent = pHead;
while(pCurrent)
{
pCurrent->Afficher();
pCurrent = pCurrent->pNext;
}
SDL_Flip(Ecran);
}

fichier declarations.h :

#include <stdlib.h>
#include <Sdl/SDL.h>
#include "objet.h"

// Variablesconst int LARGECRAN 640, HAUTECRAN 480; // en pixelsconst int LARGOBJET 32, HAUTOBJET 32; // en pixelsconst int LARGMAP 50, HAUTMAP 30; // en tiles
int XCamera, YCamera; // en tiles
SDL_Surface *Ecran = NULL;
Objet *pHead = NULL;

// Fonctions
void Initialiser();
void AttendreEvenements();
void Afficher();

fichier objet.h :

class Objet
{
public:
Objet(char[],int,int);
void Afficher();
Objet *pNext;
private:
int x,y;
SDL_Surface *SurfObj;
SDL_Rect RectObj;
};

/* Le constructeur prend pour argument le chemin d'accès à la texture
à charger, l'abscisse de l'objet et son ordonnée (exprimées en tiles,
pas en pixels !). L'affichage se fait par l'appel de la fonction
Afficher(). */

fichier objet.cpp :

#include "declarations.h"

Objet::Objet(char* texture, int abs, int ord)
{
SurfObj = SDL_LoadBMP(texture); x abs; y ord;
// Ajout à la liste chaînée
pNext = pHead;
pHead = this;
}

void Objet::Afficher()
{
RectObj.x = (x - XCamera) * LARGOBJET;
RectObj.y = (y - YCamera) * HAUTOBJET;
if(RectObj.x >= 0 && RectObj.x < LARGECRAN &&
RectObj.y >= 0 && RectObj.y < HAUTECRAN)
{
SDL_SetColorKey(SurfObj,SDL_SRCCOLORKEY,SDL_MapRGB(SurfObj->format,
255,0,0));
SDL_BlitSurface(SurfObj,NULL,Ecran,&RectObj);
}
}

Erreurs de compilation :
Elles sont du type : multiple definition of `XCamera'
et :
[Linker error] undefined reference to `__gxx_personality_v0'

Voila, j'espère que vous aurez le courage d'examiner tout ça et de m'aider... merci d'avance !

5 réponses

Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
6 juil. 2004 à 19:52
Salut,

deux choses.
1. dans les fichiers d'include (.h) on met des include-guard
ex:
#ifndef __DECLARATIONS_H__INCLUDED__
#define __DECLARATIONS_H__INCLUDED__

... // tout ton code

#endif

2. Pour les variables globales, il faut les déclarer extern
dans le .h

int XCamera, YCamera; // en tiles

devient

extern int XCamera;
extern YCamera;

et tu crées un fichier .cpp contenant
les lignes

int XCamera, YCamera; // en tiles
...

que tu compiles/link avec ton projet final

Ces deux points devraient te permettre de corriger quelques erreurs.

//Ma participation à la saturation du net:
//http://hylvenir.free.fr
Tijee Messages postés 11 Date d'inscription mardi 6 avril 2004 Statut Membre Dernière intervention 22 juillet 2004
6 juil. 2004 à 20:44
Hylvenir, mon premier mot sera : merci... merci d'avoir répondu !
J'ai modifié le fichier declarations.h comme suit :

#ifndef __DECLARATIONS_H__INCLUDED__
#define __DECLARATIONS_H__INCLUDED__

#include <stdlib.h>
#include <Sdl/SDL.h>
#include "objet.h"

// Variablesextern const int LARGECRAN 640, HAUTECRAN 480; // en pixelsextern const int LARGOBJET 32, HAUTOBJET 32; // en pixelsextern const int LARGMAP 50, HAUTMAP 30; // en tiles
extern int XCamera, YCamera; // en tiles
extern SDL_Surface *Ecran;
extern Objet *pHead;

// Fonctions
void Initialiser();
void AttendreEvenements();
void Afficher();

#endif

et j'ai créé un fichier declarations.cpp :

#include "declarations.h"

// Variables
int XCamera, YCamera; // en tiles
SDL_Surface *Ecran = NULL;
Objet *pHead = NULL;

Mais j'ai toujours les mêmes problèmes... je pense que ça vient de moi, j'aimerais bien que tu m'expliques l'utilité de ce que tu m'as conseillé pour que je comprenne ce que je fais et que j'évite ainsi les bourdes que j'ai du commettre...
Thanks ! :)
cs_AlexMAN Messages postés 1536 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 24 mai 2009 1
6 juil. 2004 à 20:57
#ifndef __DECLARATIONS_H__INCLUDED__
#define __DECLARATIONS_H__INCLUDED__

Cette ligne n'est pas inclure comme tel ds un fichier en tete, il faut la personnaliser, et peu importe en fait le nom ke lon va utiliser, mais une syntaxe commune a tout les programmeurs a été décidé, une sorte de 'norme' :

exemple : ds ton fichier objet.h, tu feras ca :

#ifndef OBJET_H
#define OBJET_H

Et ensuite, pour ce ki est des declarations, jne suis pas d'acccord avec Hylvenir : il faut declarer les variables ds le header come ca : int X; et ensuite, facultativement, les redeclarer ds le fichier cpp comme suit : extern int X;

Voila ++

Alhexman
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
7 juil. 2004 à 08:52
Tijee > tu n'as pas besoin de mettre extern si ta variable est const.

Tu remarqueras que tu n'as pas non plus besoin de mettre extern devant les déclérations de fonction car par défaut elle sont extern (d'ou le Undefined Symbol au link)

Les "include-guard" évite d'inclure plusieurs fois lors de la compilation des variables dites globales, ce qui évite de duplicate symbol . Le __DECLARATIONS_H__INCLUDED__ doit être adapté selon le nom de ton fichier .h
Tu choisis une norme, et tu t'y tiens pour ton projet.

__DECLARATIONS_H__INCLUDED__
__OBJET_H__INCLUDED__
...
tu as compris je pense ;-)

Quand tu déclares( extern int X; )une variables extern, tu dis juste au compilateur que cette variable existe donc pas besoin de faire "Declaration Missing" par exemple.
Quand tu définis cette même variable dans le .cpp ( int X; )
tu dis à l'éditeur de lien 'ou se trouve' cette variable
ce qui évite le Undefined Symbol.
Pour te rafraichir la mémoire regarde le Langage C++
de Stroustrup le chapitre sur les déclarations.

AlexMan > ce serait tellement plus simple si tous les programmeurs étaient d'accord ;-)

Mais tu risques d'avoir des duplicate symbol en cas de multiple inclusion de tes includes.
La norme que tu donnes sur les noms des defines est un peu légère. Prends plutôt celle de Lakos (Large Scale C++ Software Design)

// Ma participation à la saturation du net:
// http://hylvenir.free.fr

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Tijee Messages postés 11 Date d'inscription mardi 6 avril 2004 Statut Membre Dernière intervention 22 juillet 2004
7 juil. 2004 à 09:46
Ok les gars merci pour vos réponses je vais rectifier tout ça ! ;)
Rejoignez-nous