Acquis de conscience en c++ ? [Help] - Programmation
Marsh Posté le 17-12-2001 à 08:48:47
hello, 
 
quand tu fais une allocation dynamique, c'est TOUJOURS à toi de faire la désallocation (sauf pour certaines API très particulières dont on ne parlera pas ici). 
 
Les détruire explicitement dans le detructeur me semble une bonne idée  Personnellement, quand je fait une désallocation, je mets TOUJOURS ensuite le pointeur à NULL. Et donc dans le destructeur, tu peux faire un
 Personnellement, quand je fait une désallocation, je mets TOUJOURS ensuite le pointeur à NULL. Et donc dans le destructeur, tu peux faire un 
if(ptr != NULL) 
{ 
    delete [] ptr; 
    ptr = NULL; 
} 
 
A priori cela ne coute pas grabd chose. 
 
Par contre attention, car si tu utilises ce tableau dans une autre classe et que la classe qui l'a crée, il peut y avoir un soucis  Attention donc de ne pas utiliser le tableau une fois qu'il a été détruit
 Attention donc de ne pas utiliser le tableau une fois qu'il a été détruit  
 
 
a+ 
Marsh Posté le 17-12-2001 à 09:24:01
| SoWhatIn22 a écrit a écrit  : hello, quand tu fais une allocation dynamique, c'est TOUJOURS à toi de faire la désallocation (sauf pour certaines API très particulières dont on ne parlera pas ici). Les détruire explicitement dans le detructeur me semble une bonne idée  Personnellement, quand je fait une désallocation, je mets TOUJOURS ensuite le pointeur à NULL. Et donc dans le destructeur, tu peux faire un if(ptr != NULL) { delete [] ptr; ptr = NULL; } A priori cela ne coute pas grabd chose. Par contre attention, car si tu utilises ce tableau dans une autre classe et que la classe qui l'a crée, il peut y avoir un soucis  Attention donc de ne pas utiliser le tableau une fois qu'il a été détruit   a+ | 
 
 
Bah, si le programme est bien fait, ce tableau ne doit être accessible par l'intermédiaire de l'instance qui contient le tableau. Si le tableau est désalloué dans le destructeur de l'instance qui contient le tableau, impossible de tenter d'utiliser le tableau du moment qu'il à été détruit ! c qd même génial l'objet ! 
Marsh Posté le 17-12-2001 à 11:02:10
Le destructeur n'est appele que dans les cas suivants: 
- tu arrives a la fin du scope de ton objet 
(alloue sur la pile => destruction automatique en fin 
de procedure, objet membre => 
destruction automatique a la destruction de l'objet 
qui le contient, allocation globale => destruction a la sortie de l'application) 
- tu appelles delete sur cet objet (si celui-ci a  
ete prealablement alloue par new). 
 
Quand je dis "objet membre" cela exclut bien evidemment 
les pointeurs et les references. Dans ce cas, il faut definir 
QUI doit detruire les objets pointes ou references. C'est a toi de definir ta convention, mais il faut s'y tenir strictement parce que chaque objet ne peut etre detruit qu'une seule fois (sinon plantage!). 
 
A+ 
LEGREG 
Marsh Posté le 17-12-2001 à 14:16:48
merci pour tout ca, mais cela n'arrange pas mon affaire, car le fait de detruire une objet membre ds le destructeur , voir meme ailleurs pose des problemes (ERROR / DAMAGE ...) 
je vous pose ma class 
 
class Ligne 
{ 
 private : 
 	short* ligne; 
 	... 
 public : 
 	Ligne(); 
 	void Saisir(int taille); 
                 ... 
 	~Ligne(); 
}; 
quand je saisis un objet de Ligne je fais a l'interieur un 
ligne = new short [taille] ; 
donc je renseigne la donnée membre ligne 
 
mais si je met ds le destructeur ou meme ailleur un delete [] ligne 
ou meme un free(ligne) (qUI n'appelle pas le destructeur) 
j'ai un gros message d'erreur 
quoi faire pour dessalouer cette !!!! de memoire ? 
Marsh Posté le 17-12-2001 à 14:22:35
un truc possible : ton membre ligne appartient à la classe Ligne ... peut être qu'il aime pas trop ça !
Marsh Posté le 17-12-2001 à 14:36:19
ben logiquement non car  
le tableau de short ligne est en minuscule 
et la classe Ligne est en majuscule  
(je parle du "L" ) 
donc il s'agit de 2 chose differente 
Marsh Posté le 17-12-2001 à 14:37:11
ok je viens de capter 
oui c ca et je pense (suis presque sur) que le probleme vient de la 
et je cherche en faite la technique pour contourner ce prob 
Marsh Posté le 17-12-2001 à 14:43:44
...bah, changer le nom de ton membre !! 
d'ailleur normalement, on préfixe les attributs de classe par m_, puis une lettre qui indique le type du membre. Si ton prog était écrit selon les normes, ça donnerai 
m_lpsLigne. 
lp signifiant qu'il s'agit d'un pointeur 
Marsh Posté le 17-12-2001 à 14:44:00
| Rob Roy a écrit a écrit  : merci pour tout ca, mais cela n'arrange pas mon affaire, car le fait de detruire une objet membre ds le destructeur , voir meme ailleurs pose des problemes (ERROR / DAMAGE ...) je vous pose ma class class Ligne { private : short* ligne; ... public : Ligne(); void Saisir(int taille); ... ~Ligne(); }; quand je saisis un objet de Ligne je fais a l'interieur un ligne = new short [taille] ; donc je renseigne la donnée membre ligne mais si je met ds le destructeur ou meme ailleur un delete [] ligne ou meme un free(ligne) (qUI n'appelle pas le destructeur) j'ai un gros message d'erreur quoi faire pour dessalouer cette !!!! de memoire ? | 
 
 
deja tu commences par ne pas utiliser free sur un objet 
alloue par new! new ce n'est pas un malloc. 
 
Ensuite es-tu sur d'appeler toujours ton destructeur 
sur un membre initialise? 
(par exemple tu peux l'initialiser a NULL 
tant qu'il n'est pas rempli et 
faire le test de SoWhatIn dans le destructeur) 
 
A+ 
LEGREG 
Marsh Posté le 17-12-2001 à 14:50:27
oui j'en suis certain ! 
mon main pour le test est  
 
Ligne P; 
P.Saisir(2); 
P.Afficher(); 
 
et c tout 
et il trouve le moyen de me foutre une erreur qund je fais un delete [] ligne ds le constructeur ! 
Marsh Posté le 17-12-2001 à 14:54:51
essaie de poster le code complet du truc 
ou un exemple simple qui plante 
j'crois qu'il nous manque du materiel 
pour juger.. 
 
LEGREG 
Marsh Posté le 17-12-2001 à 15:08:30
| El_Gringo a écrit a écrit  : ...bah, changer le nom de ton membre !! d'ailleur normalement, on préfixe les attributs de classe par m_, puis une lettre qui indique le type du membre. Si ton prog était écrit selon les normes, ça donnerai m_lpsLigne. lp signifiant qu'il s'agit d'un pointeur | 
 
 
non je sais tout ca mais comme mon binome est un nb de chez nb en c++ (ce qui ne veut pas dire que je soit un boss) ds un premier tps on avait pris des termes tout simple.Mais cela ne change rien de tte facon ! 
 
enfin bon voila mon code simplifié de tout ce qui n'est pas important 
class CLigne 
{ 
 private : 
 	short* m_lpsLigne; 
 	... 
 public : 
 	CLigne(); 
 	void Saisir(int taille); 
                ... 
1  ~CLigne(); 
 
}; 
 
void CLigne::Saisir(int taille) 
{  
 m_lpsLigne = new short [taille] ;  
 for (int i=1;i<=taille;i++) 
 { 
 	cin >> m_lpsLigne[i]; 
 } 
} 
 
CLigne::~CLigne() 
{ 
 delete [] m_lpsLigne; 
} 
 
edit : et mon main n'est qu'un simple  
CLigne L; 
L.Saisir(3); et c tout !!! 
[edtdd]--Message édité par Rob Roy--[/edtdd]
Marsh Posté le 17-12-2001 à 15:13:20
| Rob Roy a écrit a écrit  : void CLigne::Saisir(int taille) { m_lpsLigne = new short [taille] ; for (int i=1;i<=taille;i++) { cin >> m_lpsLigne[i]; } } | 
 
 
attention un tableau en C/C++ 
commence a 0 et finit a taille-1. 
 
[OT] 
Je ne sais pas si c'est plus logique qu'une autre 
numerotation et je ne veux pas le savoir mais 
c'est comme ca  
 
[/OT] 
 
LEGREG 
Marsh Posté le 17-12-2001 à 15:37:16
merci pour ce ptit detail que j'avais oublié  
nmais ca marche pas mieux, car en fait meme si mes tableaux etait plus grand que la normal (...) l'espace etait quand meme alloué et le probleme reste le meme ! 
Marsh Posté le 17-12-2001 à 15:39:28
j'crois qu'il faut que tu rajoutes encore 
un bout de ton programme.. 
 
LEGREG 
Marsh Posté le 17-12-2001 à 15:48:17
nop ca suffit car le prog plante quand mon main a => 
 
void main() 
{ 
 CLigne P; 
 P.Saisir(2); 
} 
 
ridicule quoi 
Marsh Posté le 17-12-2001 à 16:04:52
ben tu as l'air de savoir la ou ca plante 
malheureusement 
je crois qu'il nous manque encore du code 
 
=> pourquoi ne pas nous donner au moins 
toute l'implantation de CLine? 
 
J'imagine egalement que le "1"devant la declaration de "~CLigne()" 
est une erreur de copier-coller.. 
 
LEGREG 
Marsh Posté le 17-12-2001 à 16:08:41
class CLigne 
{ 
 friend class CMatrice; 
 private : 
 	short* m_lpsLigne; 
 	bool m_bOnly0; 
 public : 
 	CLigne(); 
 	void Saisir(int taille); 
 	void Afficher(); 
 	void Ajouter(CLigne L); 
 	~CLigne(); 
 
}; 
Marsh Posté le 17-12-2001 à 16:10:40
en passant ya t'il un moyen d'empecher l'utilisateur de taper autre chose qu'un int ou un short dans un cin ou encore un moyen de tester les valeur que l'utilisateur rentre ?
Marsh Posté le 17-12-2001 à 16:24:45
| Code : 
 | 
 
 
Sinon, je veux bien jouer au puzzle 
mais ca va etre dur de t'aider 
 
LEGREG 
Marsh Posté le 17-12-2001 à 16:36:14
merci pour qui ya en haut 
euh j'ai tout mis  
je remet tout ds un post if y like 
 
 
class CLigne  
{  
friend class CMatrice;  
private :  
 short* m_lpsLigne;  
 bool m_bOnly0;  
public :  
 CLigne();  
 void Saisir(int taille);  
 void Afficher();  
 void Ajouter(CLigne L);  
 ~CLigne();  
 
};  
 
 
CLigne::CLigne() 
{ 
 m_lpsLigne=NULL; 
 m_bOnly0=true; 
} 
 
void CLigne::Saisir(int taille) 
{   
m_lpsLigne = new short [taille-1] ;   
for (int i=0;i<=taille-1;i++) 
{ 
 cin >> m_lpsLigne[i]; 
} 
} 
 
CLigne::~CLigne() 
{ 
delete [] m_lpsLigne; 
} 
 
void main()  
{  
CLigne P;  
P.Saisir(2);  
} 
Marsh Posté le 17-12-2001 à 17:13:15
quand je disais qu'un tableau ca va de 0 a taille-1 
taille c'est la taille du tableau 
et il faut donc faire un  
tableau = new short[taille]; <-- cree un tableau a taille element 
numerotes de 0 a taille-1 
 
LEGREG 
Marsh Posté le 17-12-2001 à 17:23:37
le std c'est juste pour dire que cin et cout  
sont definis dans l'espace de nom std 
 
Tu peux eviter de preciser l'espace de nom 
a chaque fois en mettant une fois pour toute 
au debut de ton fichier 
using namespace std; 
 
par contre je ne vois pas ou tu as mis 
ton  
#include <iostream>  
c'est le fichier qui contient les definitions 
de cin et cout 
 
A+ 
LEGREG 
Marsh Posté le 17-12-2001 à 02:26:27
je créé une classe composé ayant comme donnée membre un tableau dynamique et d'autres trucs
a chaque fois que je créé un objet de cette classe je 'alloue (new ...) donc ce tableau dynamique pour le reutiliser plus tard ds une autre classe.
Ma question concerne en realité le destruceur. Dois-je desallouer par delete les tableaux que je créé, a la fin de mon programme, ou le destructeur se charge t'il de le faire pour moi.
Sinon comment faire ?
Merchi
++