Problème de stack overflow avec classe

Signaler
Messages postés
13
Date d'inscription
mercredi 10 octobre 2007
Statut
Membre
Dernière intervention
12 octobre 2008
-
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
-
Bonjour,

Je suis un petit nouveau et j'ai déja un problème en cpp ;) ! Je suis à la recherche d'une bonne âme pour m'aider !
voici mon pb :

J'ai deux class dans mon prog : Student et Course, et chacune d'elle ont en private un tableau d'objet de l'autre class.
(cad : Student cont un tableau de course et Course contient un tableau de student !).
Donc vous voyez venir le problême à grande enjambée : STACK OVERFLOW , boucle infini dès que je crée un objet !
Mais voilà, mes class sont obligées de contenir des tableaux de l'autre class. Alors SVP comment contourner le pb ?

Merci de vos réponses ;)

18 réponses

Messages postés
317
Date d'inscription
vendredi 25 mai 2007
Statut
Membre
Dernière intervention
19 octobre 2007

Bonjour,

Oui c'est tout à fait possible d'avoir une définition récursive de tes classes, tu peux dire que Student contient des Courses
et que Courses contient des Students ça donnerait quelque chose du genre:
 class Student {
 private:
 Courses courses[10];
 }
class Courses {
 private:
 Student students[40];
}
 maintenant, ton stack overflow vient peut-être d'une mauvaise utilisation de tes tableaux et si tu collais un bout de code on pourrait voir pour t'aider plus :p

=

Une autruche ne se cuit pas aux petits lardons
Messages postés
338
Date d'inscription
samedi 9 août 2003
Statut
Membre
Dernière intervention
9 juillet 2011
2
tu peux utilisé des pointeurs dans ta classe comme cela tu ne créeras pas toujours des objects en pile mais seulement ce que tu as besoins
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
NON ! on ne peut pas avoir de définition récursive !

Ca, c'est totalement incorrect:
 class Student {
 private:
 Courses courses[10];
 }
class Courses {
 private:
 Student students[40];
}

C'est simple a comprendre. Un Student contient 10 Courses qui possèdent chacun 10 Studient, etc ...
donc la taille de ta classe est infinie ....

La seule solution possible c'est ca:
class Student {

 private:

 Courses * courses[10];

 }

class Courses {

 private:

 Student * students[40];

}
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Une autre facon de le faire, c'est d'utiliser des vecteurs:
class Student {
 private:
  std::vector<Courses> courses;
 }
class Courses {
 private:
  std::vector<Student> students;
}

Mais, la seule solution bien adaptée, ce sont les pointeurs puisque du coup, il n'y a qu'un objet Student par élève, et non une copie de l'objet Student dans chaque Cours.
Messages postés
317
Date d'inscription
vendredi 25 mai 2007
Statut
Membre
Dernière intervention
19 octobre 2007

RE,

ben en java tu peux, après tu peux faire avec un * ou avec un & et c'est bon en C++
Donc, OUI, tu peux.

Une autruche ne se cuit pas aux petits lardons
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Que Java le permette, ca me parait douteux, je vois pas comment il peut s'en sortir.

Bien sur qu'on peut faire des classes récursives en C++, mais ce n'est pas des objets, mais des pointeurs qu'il faut utiliser. Ca n'a rien à voir... c'est pas juste une petite étoile à côté du type.
Pour les références "&" c'est inutilisable pour un membre de classe sauf cas très (très !) particulier.
Messages postés
317
Date d'inscription
vendredi 25 mai 2007
Statut
Membre
Dernière intervention
19 octobre 2007

Ah oui, ok, je comprends mieux luhtor et tu as raison, en fait, je confonds.. Merci de avoir corriger pour que je ne déroute pas ce mec. :p


=

Une autruche ne se cuit pas aux petits lardons
Messages postés
13
Date d'inscription
mercredi 10 octobre 2007
Statut
Membre
Dernière intervention
12 octobre 2008
1
Merci pour vos réponses et désolé pour la mienne tardive (je suis au Canada, donc forcément légerement en décalage ;) )

Bon en fait mon problème n'a pas de solution, la boucle infinie est innévitable, la seule solution possible et d'utiliser des listes à la place des tableaux !! Même avec les vectors cela ne fonctionne pas !

A bientôt !
Messages postés
338
Date d'inscription
samedi 9 août 2003
Statut
Membre
Dernière intervention
9 juillet 2011
2
2 jour de decalage c'est long et moi aussi je viens du canada .

avec des pointeur cela ne creer pas de boucle infinie tu n'as qua creer une methode ex CreerEtudient
et creerCours

qui creera ton tableau de x nombre et dans tes constructeur mais ton pointeur à 0 . donc il n'aura pas a appeler le constructeur et vise versa.

comme je te l'ai dit dans mon premier message les pointeurs sont la solution
pense au liste chainé pas de pointeur ca creerais une boucle infinie
Messages postés
13
Date d'inscription
mercredi 10 octobre 2007
Statut
Membre
Dernière intervention
12 octobre 2008
1
rebonjour,

Je vois vraiment pas comment faire avec les pointeurs. Voici le code que j'ai.

Pour la class student je declare en private mon tableau de course:

Course *courl;

et dans le constructeur je l'initialise à :

courl=
new Course[10];

De même dans ma classe Course j'ai en private :


Student *studentlist;

et dans le constructeur je l'initialise à :


studentlist=new Student[10];



Cette méthode cela ne fonctionne pas du tout : STACK OVERFLOW !
Donc pourriez vous me montrer explicitement avec des morceaux de codes ;)
  !
Messages postés
338
Date d'inscription
samedi 9 août 2003
Statut
Membre
Dernière intervention
9 juillet 2011
2
 class Student {
public:
void SetNbCours(int iNbCours);
const Cours & GetCours(int iCours);
Student();
virtual ~Student();
 private:
 Courses *m_pcourses;
int m_iNbCours;
 };
class Cours {
public:

void SetNbStudents(int iNbStudents);

const Students& GetStudents(int iStudents);

Cours ();
virtual ~Cours ();

 private:
 Student *students;
int m_iNbStudents;
};

dans tes constructeurs tu appellles SetNb...(0);
dans SetNb...  tu verifies si le pointeur a deja ete initialiser si oui tu le supprime sinon tu le creer avec le nombre en parametre
et dans get.... tu peux renvoyer un object de ton pointeur
a ton destructeur tu supprimes le tableau
Messages postés
13
Date d'inscription
mercredi 10 octobre 2007
Statut
Membre
Dernière intervention
12 octobre 2008
1
Euh, jai pas bien tout compris :


Tu initialise tout les tableaux comme moi , sauf que dans le constructeurs tu appel ta fonction setnb() mais le truck c'est que tu passe un nb d'élève dans cette fonction donc cela revient à le crée directement comme moi : studentlist=new Student[10];
(pour 10 éleves), après je comprend pas du tout ton appel de destructeur .
Messages postés
13
Date d'inscription
mercredi 10 octobre 2007
Statut
Membre
Dernière intervention
12 octobre 2008
1
Euh, jai pas bien tout compris :


Tu initialise tout les tableaux comme moi , sauf que dans le constructeurs tu appel ta fonction setnb() mais le truck c'est que tu passe un nb d'élève dans cette fonction donc cela revient à le crée directement comme moi : studentlist=new Student[10];
(pour 10 éleves), après je comprend pas du tout ton appel de destructeur .
Messages postés
338
Date d'inscription
samedi 9 août 2003
Statut
Membre
Dernière intervention
9 juillet 2011
2
pour ne pas avoir de probleme le constructeur ne dois pas creer les eleves ou cours tu devras donc faire

int main()
{
Student oStudent;
oStudent.SetNbCours(10);
}

ton code creera un eleve avec 10 cours c'est tout.

le destructeur sers a detruire le pointeur donc dans ton constructeur il aura
delete [] m_pCours;
Messages postés
13
Date d'inscription
mercredi 10 octobre 2007
Statut
Membre
Dernière intervention
12 octobre 2008
1
Ah ok je vois mieux !

mais quand je vais appeler oStudent.SetNbCours(10); dans le main cela mettra 10 cours à mes student, et les tableaux de student dans les 10 cours seront quand à eux initialiser à 0 pour le moment, donc pas de boucles infinies !
ais-je bien compris ?
Messages postés
338
Date d'inscription
samedi 9 août 2003
Statut
Membre
Dernière intervention
9 juillet 2011
2
c''est cela et tu peux utiliser ensuite getCours(0).SetNbStudent(30);
sauf enleve le const
Messages postés
13
Date d'inscription
mercredi 10 octobre 2007
Statut
Membre
Dernière intervention
12 octobre 2008
1
Ok merci,
je vais essayer !!
A bientôt !
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
C'est pourtant pas compliqué :)
La solution des std::vector est la plus simple (si elle marche !), mais les pointeurs fonctionnent très bien.

[auteur/GAMEMONDE/147537.aspx gamemonde] a proprosé ca:


class Student {
...
   Courses *m_pcourses;
   int m_iNbCours;
 };

Tu peux aussi utiliser ca, qui est peut etre un peu plus proche de ton code:


class Student {

...

   Courses * m_pCourses[10];

   int m_nbCours;

 };