PDA

Voir la version complète : SDL_Rect n'aime pas les pointeurs (?)


TrizoLakai
16/10/2005, 09h32
Ce programme compile bien mais me fais des erreurs à cause des pointeur sur SDL_Rect.


SDL_Rect Rect_A, Rect_B;
Rect_A.x = 20;
Rect_A.y = 10;
Rect_A.w = 10;
Rect_A.h = 20;

Rect_B.x = 34;
Rect_B.y = 0;
Rect_B.w = 10;
Rect_B.h = 20;


Physique A, B;
A.Load(10, &Rect_A);
B.Load(12, &Rect_B);


Ma classe :

[...]
SDL_Rect *Rectangle; //en private:
[...]
void Load(int vit, SDL_Rect *Rect); //en publique:


Fonction Load:

void Physique::Load(int vit, SDL_Rect *Rect){
vitesse = vit;
*Rectangle = *Rect;
}


Voila ça me fait des erreur au lancement de l'appli. Pouvez-vous m'aider parce que ce serai super pratique d'avoir des pointeur. :00000010:

Merci :00000023:

TrizoLakai
16/10/2005, 09h47
Bon j'ai trouvé SDL_Rect *Rect_A = new SDL_Rect;

Mais le problème c'est que je n'arive pas à partager la mémoire du Rectangle entre le premier bout de code et la classe.

Si je change la valeur d'un rectangle et que dans la classe j'affiche le rectangle (cout << Rectangle->x) Et bien ça me sort la valeur de l'initialisation. :00000032:

Mokona
16/10/2005, 12h21
Une des réponses à ta première erreur était plutôt :

SDL_Rect Rectangle; //en private:


puis

void Physique::Load(int vit, const SDL_Rect &Rect){
vitesse = vit;
Rectangle = Rect;
}


avec pour appel


A.Load(10, Rect_A);
B.Load(20, Rect_B);


Quand tu écris SDL_Rect *Rectangle; dans ta classe, tu stockes un pointeur sur un SDL_Rect, mais tu n'alloue aucune mémoire pour un stockage de SDL_Rect.

Or, quand tu fais *Rectangle = *Rect;m tu dis : copie moi le SDL_Rect (dans son intégralité) dans le SDL_Rect pointé par Rectangle... qui n'existe pas si tu ne l'as pas initialisé.

Il y a d'autres réponses possibles :

dans la classe


SDL_Rect VraiRectangle;
SDL_Rect * Rectangle;


Et dans le constructeur de la classe : Rectangle = &VraiRectangle;

Ou bien, encore une autre possibilité, dans le constructeur :

Rectangle = new SDL_Rect


sans oublier le delete Rectangle dans le destructeur.

Maintenant, je ne comprends pas ta seconde question... Ou plutôt, j'ai peur de comprendre. Ta classe _copie_ les valeurs de SDL_Rect que tu passes en paramètres. En changeant les valeurs que tu as passé en paramètre ultérieurement, ça ne changera rien, puisque ce sont des SDL_Rect différents.

Ou alors, tu voulais, initialement, écrire :

Rectangle = Rect;

Dans ce cas, le pointeur Rectangle pointe sur tes SDL_Rect du premier bout de code. Mais ATTENTION, dans ton premier bout de code, visiblement, tes SDL_Rect sont des variables locales. Cela signifie que dès que la portée de ses variables est terminée, elles vont être détruites et le pointeur Rectangle sera invalide (il pointera sur n'importe quoi).

TrizoLakai
16/10/2005, 13h15
Le "Vrairectangle" est crée en dehors de la classe :


[...]
SDL_Rect Rect_A; //Je crée un rectangle

Physique B //Creation d'un objet B de la classe Physique

Rect_A.x = 20;

A.Load(&Rect_A);
A.Control(); //me renvoi 20 => OK

Rect_A.x = 679;
A.Control(); //me renvoi 20 si ça ne me faisait pas d'erreur=>PAS OK
[...]


La classe :

Physique{
Private:
SDL_Rect *Rectangle;
Public :
void Load(SDL_Rect *A_Copier);
void Control(){cout << Rectangle->x << endl};
};

void Physique::Load(SDL_Rect *A_Copier){
*Rectangle = *A_Copier
}


Tu vois en fait je veut conserver le Rect_A parce que il sera soumis à plusieur classe. Et donc quand je change la valeur de Rect_A.x ça change pour toute les classes :00000010:

Ced666
16/10/2005, 14h07
Hum, pour répondre à ta question: tu dois sauver le pointeur lui-même et pas le contenu sauvé. Remplace le code:

void Physique::Load(SDL_Rect *A_Copier){
*Rectangle = *A_Copier
}

par le code:

void Physique::Load(SDL_Rect *A_Copier){
Rectangle = A_Copier
}

Comme ça Rectangle pointera au même emplacement mémoire que le pointeur que tu passe en argument de la fonction.

Bon, à part ta question, je pense que ce ne soit pas vraiment une très bonne méthode de travailler comme ça. En effet, quand tu fais ceci:

SDL_Rect Rect_A; //Je crée un rectangle

Physique B //Creation d'un objet B de la classe Physique

Rect_A.x = 20;

A.Load(&Rect_A);
A.Control(); //me renvoi 20 => OK

Rect_A.x = 679;
A.Control(); //me renvoi 20 si ça ne me faisait pas d'erreur=>PAS OK

ce qui va se passer c'est que tu vas envoyer l'adresse d'un objet temporaire (en l'occurence Rect_A). Cet objet sera détruit à la fin de la fonction dans laquelle il a été créé (c'est ce qu'on appelle la 'durée de vie' ou scope en anglais). Donc une fois que ta fonction est terminée, les données pointées ne sont plus valides et ne sont également plus protégées !! Ce qui veut dire que les données peuvent changer n'importe quand.
Une solution au problème serait de créer ton objet dynamiquement (avec new) ce qui te permettrait de contrôler sa durée de vie (tu détruit l'objet avec delete, avant ça, les données restent valides).

Mais bon, je en suis pas sûr non plus que ce soit le design idéal ;-). Pourquoi est-ce que ce rectangle doit être partagé entre plusieurs objets ? Si tu veux que ce rectangle soit partagé entre TOUS les objets Physique, tu peux simplement le déclarer statique (static) dans la classe elle-même (à ce moment là, il sera partagé par toutes les instances de ta classe Physique.

TrizoLakai
16/10/2005, 18h29
Merci pour ta réponse. Je vais surement utiliser new et delete.

Pour le rectangle il doit être partagé non pas avec chaque objet physique mais avec d'autre classe (déplacement par exemple) et pour vérifier les collision j'ai besoin également du même rectangle (pour avoir les même position) dans la classe "Physique". Je ne sais pas si je me fais bien comprendre. :00000010:


ps : Ca fonctionne à merveille encore merci.