Question sur les pointeurs...

Question sur les pointeurs... - C++ - Programmation

Marsh Posté le 02-05-2003 à 00:26:24    

Salut,
 
encore moi pour une question, cette fois-ci sur les pointeurs:
 
je "programme" avec Borland C++ Builder 6.0...
 
j'utilise la variable AnsiString TableauStats[] dans de nombreux fichiers dans mon projet, mais uniquement en lecture. C'est un tableau contenant plusieurs chaines de caractères, et qui n'est jamais modifié. Je l'ai déclaré en public dans le .h de ma fiche principale, nommée MainForm.
 
Donc dans les autres fiches, quand j'en ai besoin, j'y accède grâce à MainForm->TableauStats[]...
 
Le problème est que ça fait long à taper dans le code. Donc j'ai pensé aux pointeurs, mais je comprends pas trop bien. J'ai lu différentes explications, notamment dans le cours de Casteyde, mais bon, je suis paumé...
 
Je voudrai donc "remplacer" MainForm->TableauStats[] dans le code par ListeStats par exemple, mais avec ListeStats qui pointerait vers TableauStats[].
 
Comment je fais ça?
 
Merci d'avance!!

Reply

Marsh Posté le 02-05-2003 à 00:26:24   

Reply

Marsh Posté le 02-05-2003 à 00:39:42    

Code :
  1. AnsiString *ListeStats = MainForm->TableauStats;


 
devrait te suffire ...


---------------
last.fm
Reply

Marsh Posté le 02-05-2003 à 18:57:49    

theShOcKwAvE a écrit :

Code :
  1. AnsiString *ListeStats = MainForm->TableauStats;


 
devrait te suffire ...


 
D'accord...
 
Et on l'utilise comment?
 
*ListeStats?
&ListeStats?
ListeStats?
 
Merci!

Reply

Marsh Posté le 02-05-2003 à 23:09:38    

Bon là ça marche pas...
 
Je fais un gros post, mais j'explique tout en détail, comme ça vous galérerez moins :D  
 
Dans MainForm, j'ai ça:
 

Code :
  1. AnsiString TableauStats[] = { "LFL", "LFR", "T2L", "T2R", "T3L"
  2. , "T3R", "RD", "RO", "PD", "INT", "CON", "FP", "FC", "BP" };
  3. AnsiString TableauNomStats[] = { "Lancer Franc Raté", "Lancer Franc Réussi",
  4. "Tir à 2 points raté", "Tir à 2 points réussi",
  5. "Tir à 3 points raté", "Tir à 3 points réussi",
  6. "Rebond Défensif", "Rebond Offensif", "Passe Décisive","Interception",
  7. "Contre", "Faute Provoquée","Faute Commise", "Balle Perdue" };
  8. int CouleurStats[] = { 0x02808080 ,0x02FFFF00 ,0x0200FF00 ,0x0200FFFF ,
  9. 0x020000FF ,0x02FF00FF ,0x02FF9000 ,0x02AE01FF ,0x02FFFFFF ,
  10. 0x0201FFC0 ,0x02BAFF01 ,0x02C0C0C0 ,0x02FF0000 ,0x02C0C0FF  };


 
Ce sont trois variables globales...
 
Dans une autre fiche, je dois utiliser TableauStats[].
 
Si je déclare un pointeur comme ceci:

Code :
  1. AnsiString* ListeStats = MainForm->TableauStats;


 
Il me sort:
Impossible de convertir 'AnsiString' en 'AnsiString *'
 
Si je déclare comme ça (sans pointeur)

Code :
  1. AnsiString* ListeStats = MainForm->TableauStats;


 
Là la compilation se déroule bien, mais quand la fonction qui contient cette déclaration est appellée, j'ai une erreur de Windows me disant "Violation..."
 
Si je déclare comme ça:

Code :
  1. AnsiString* ListeStats = &MainForm->TableauStats;


 
Ce coup ci j'ai pas d'erreur.
 
Mais dans cette fiche, j'ai la fonction suivante, qui contient la déclaration du pointeur:
 

Code :
  1. void __fastcall TAssistantForm::FinClick(TObject *Sender)
  2. {
  3. AnsiString* ListeStats = &MainForm->TableauStats;
  4. AnsiString PathXMLStats = FichierSaveXML->Text;
  5. AnsiString EnteteXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<Stats Nom=\"" + NomMatch->Text + "\" Date=\"" + DateMatch->Date + "\" Lieu=\"" + LieuMatch->Text + "\" Video=\"" + PathVideo->Text + "\" Position=\"0\" Termine=\"n\" AjoutStats=\"n\">" + "</Stats>";
  6. //............
  7. //............
  8. for (int i=0; i<ListeJoueursDomicile->Count; i++)
  9. {
  10.   _di_IXMLNode AjoutJoueur = AjoutJoueursDomicile->AddChild(WideString("Joueur" ));
  11.   AjoutJoueur->SetAttribute(WideString("Nom" ),ListeJoueursDomicile->Items->Strings[i]);
  12.   for (int j=0; j<ARRAYSIZE(ListeStats); j++)
  13.     _di_IXMLNode StatsJoueur = AjoutJoueur->AddChild(WideString(ListeStats[j] + "Infos" ));
  14. }
  15. //............
  16. //............


 
La dernière boucle for est celle qui pose problème...
 
Cette fonction me permet la création d'un fichier XML, et la boucle devrait me sortir des noeuds dans le XML correspondant au contenu du tableau.
 
Ex:
 

- <Joueur Nom="23 Michael Jordan">
  <LFLInfos />  
  <LFRInfos />  
  <T2LInfos />  
  <T2RInfos />  
  <T3LInfos />  
  <T3RInfos />  
  <RDInfos />  
  <ROInfos />  
  <PDInfos />  
  <INTInfos />  
  <CONInfos />  
  <FPInfos />  
  <FCInfos />  
  <BPInfos />
  </Joueur>


 
Le problème est que ces 14 lignes n'apparaissent pas...
J'ai seulement une ligne <Infos />
 
J'ai juste ça:
 

- <Joueur Nom="10 Michael Delva">
  <Infos />  
  </Joueur>


 
Si je change cette ligne:

Code :
  1. for (int j=0; j<ARRAYSIZE(ListeStats); j++)


en

Code :
  1. for (int j=0; j<ARRAYSIZE(&ListeStats); j++)


 
J'ai la même chose...
 
Comment je peux faire?
 
EDIT: typo


Message édité par haazheel le 02-05-2003 à 23:11:54
Reply

Marsh Posté le 03-05-2003 à 13:04:53    

haazheel a écrit :


Impossible de convertir 'AnsiString' en 'AnsiString *'


 
Ca veut dire qu'il te manque un niveau d'indirection ... Mais c'est surprenant : au pire, il devrait te sortir l'erreur suivante :
Impossible de convertir 'AnsiString[]' en 'AnsiString *'
 

haazheel a écrit :


Code :
  1. AnsiString* ListeStats = &MainForm->TableauStats;




 
Ca, ca devrait te sortir une erreur à la compilation, puisqu'il devrait te falloir (logiquement) un AnsiString ** pour pointer sur l'adresse de ton tableau ...
 
essaye ca, peut-être :

Code :
  1. AnsiString *ListeStats = &(MainForm->TableauStats[0]);


 
Edit : Si ca, ca ne passe pas, c'est que tableauStats n'est pas du type AnsiString[] ...


Message édité par theshockwave le 03-05-2003 à 13:06:39

---------------
last.fm
Reply

Marsh Posté le 03-05-2003 à 13:43:14    

theShOcKwAvE a écrit :


 
Ca veut dire qu'il te manque un niveau d'indirection ... Mais c'est surprenant : au pire, il devrait te sortir l'erreur suivante :
Impossible de convertir 'AnsiString[]' en 'AnsiString *'
 
 
 
Ca, ca devrait te sortir une erreur à la compilation, puisqu'il devrait te falloir (logiquement) un AnsiString ** pour pointer sur l'adresse de ton tableau ...
 
essaye ca, peut-être :

Code :
  1. AnsiString *ListeStats = &(MainForm->TableauStats[0]);


 
Edit : Si ca, ca ne passe pas, c'est que tableauStats n'est pas du type AnsiString[] ...


 
Ca passe pas... et pourtant TableauStats est bien du type AnsiString[].
 
Déclaration dans le .h:
 

Code :
  1. class TMainForm : public TForm
  2. {
  3. //..........
  4. //..........
  5. private:
  6. public:  // Déclarations de l'utilisateur
  7.   AnsiString TableauStats,TableauNomStats,NewOrOpen,
  8.              NomFichier,INIRepXML,INIRepStats;
  9.   int temps,Nombre,CouleurStats;
  10. //..........
  11. //..........
  12. };


 
Et dans le .cpp:
 

Code :
  1. //---------------------------------------------------------------------------
  2. __fastcall TMainForm::TMainForm(TComponent* Owner)
  3.         : TForm(Owner)
  4. {
  5. AnsiString TableauStats[] = { "LFL", "LFR", "T2L", "T2R", "T3L"
  6. , "T3R", "RD", "RO", "PD", "INT", "CON", "FP", "FC", "BP" };
  7. AnsiString TableauNomStats[] = { "Lancer Franc Raté", "Lancer Franc Réussi",
  8. "Tir à 2 points raté", "Tir à 2 points réussi",
  9. "Tir à 3 points raté", "Tir à 3 points réussi",
  10. "Rebond Défensif", "Rebond Offensif", "Passe Décisive","Interception",
  11. "Contre", "Faute Provoquée","Faute Commise", "Balle Perdue" };
  12. int CouleurStats[] = { 0x02808080 ,0x02FFFF00 ,0x0200FF00 ,0x0200FFFF ,
  13. 0x020000FF ,0x02FF00FF ,0x02FF9000 ,0x02AE01FF ,0x02FFFFFF ,
  14. 0x0201FFC0 ,0x02BAFF01 ,0x02C0C0C0 ,0x02FF0000 ,0x02C0C0FF  };
  15. }


 
Je comprends pas...
 
Même si je mets juste:
 

Code :
  1. ListeStats = MainForm->TableauStats;


 
Ca fonctionne pas non plus...


Message édité par haazheel le 03-05-2003 à 13:44:29
Reply

Marsh Posté le 03-05-2003 à 14:52:56    

Bon, alors ça se précise...
 
J'ai fait des tests de pointeur dans le même fichier que celui où est déclaré TableauStats...
 
Quand je ne le déclare pas dans le .h dans la catégorie public, mais que je le déclare en variable globale dans le .cpp, je peux utiliser un pointeur qui marche tout à fait bien...
 
Ex:

Code :
  1. AnsiString *p = TableauStats;
  2. ShowMessage(p[5]);


 
M'affiche bien T3L...
 
En revanche lorsque je mets dans le .h:
 

Code :
  1. public:  // Déclarations de l'utilisateur
  2.   AnsiString TableauStats,TableauNomStats,NewOrOpen,
  3.              NomFichier,INIRepXML,INIRepStats;


 
pour le même pointeur j'ai l'erreur de compilation suivante:
 

Impossible de convertir 'AnsiString' en 'AnsiString *'


 
Si je remplace la déclaration de mon pointeur par:
 

Code :
  1. AnsiString *p = &TableauStats;
  2. ShowMessage(p[5]);


 
Il compile bien mais il affiche rien...
 
Là ça dépasse mes compétences... HELP!! :sweat:

Reply

Marsh Posté le 03-05-2003 à 16:25:47    


Tu définis deux fois :
 
  AnsiString TableauStats
  AnsiString TableauStats[]
 
differement dans le .h et le .cpp
 
Tu devrais ouvrir un bouquin sur la programmation objet et l'encapsulation...  :sarcastic:


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 03-05-2003 à 17:31:08    

Tetragrammaton IHVH a écrit :


Tu définis deux fois :
 
  AnsiString TableauStats
  AnsiString TableauStats[]
 
differement dans le .h et le .cpp
 
Tu devrais ouvrir un bouquin sur la programmation objet et l'encapsulation...  :sarcastic:  


 
J'avais essayé ça pour voir...
 
Sinon maintenant j'en suis là:
 
.h

Code :
  1. public:
  2.   AnsiString TableauStats[14],TableauNomStats[14];
  3.   int CouleurStats[14];


 
.cpp (le constructeur)

Code :
  1. __fastcall TMainForm::TMainForm(TComponent* Owner)
  2.         : TForm(Owner)
  3. {
  4. TableauStats[] = { "LFL", "LFR", "T2L", "T2R", "T3L", "T3R",
  5. "RD", "RO", "PD", "INT", "CON", "FP", "FC", "BP" };
  6. TableauNomStats[] = { "Lancer Franc Raté", "Lancer Franc Réussi",
  7. "Tir à 2 points raté", "Tir à 2 points réussi",
  8. "Tir à 3 points raté", "Tir à 3 points réussi",
  9. "Rebond Défensif", "Rebond Offensif", "Passe Décisive","Interception",
  10. "Contre", "Faute Provoquée","Faute Commise", "Balle Perdue" };
  11. CouleurStats[] = { 0x02808080 ,0x02FFFF00 ,0x0200FF00 ,0x0200FFFF ,
  12. 0x020000FF ,0x02FF00FF ,0x02FF9000 ,0x02AE01FF ,0x02FFFFFF ,
  13. 0x0201FFC0 ,0x02BAFF01 ,0x02C0C0C0 ,0x02FF0000 ,0x02C0C0FF  };
  14. }


 
Si je compile comme ça, j'ai une erreur à la compilation pour chacune des 3 lignes... avec comme message d'erreur:

Syntaxe de l'expression


 
Si j'ajoute des AnsiString et int devant ces 3 lignes, je n'ai plus de problème à la compilation...
 
Dans ma deuxième classe, je définis mon pointeur comme suit:

Code :
  1. AnsiString *ListeStats;
  2. ListeStats = MainForm->TableauStats;


 
Et je n'ai pas d'erreur ni à la compil, ni à l'exécution.
 
Mais si je veux afficher ListeStats[2] par exemple, ça affiche rien du tout...
 
Comment je dois donc déclarer un pointeur sur un tableau pour pouvoir lire les données de ce tableau?
Qui plus est lorsque le pointeur et le tableau pointé sont dans deux classes différentes... Euh oui, j'avais oublié de vous dire que sur chaque .cpp, c'est une classe différente.  :lol: (Builder travaille comme ça...)

Reply

Marsh Posté le 03-05-2003 à 20:58:21    

Tu fais n'importe quoi  :pt1cable:  
 
* TableauStats[] est à utiliser quand tu déclares la variable pas pour l'initialiser
 

Citation :


Euh oui, j'avais oublié de vous dire que sur chaque .cpp, c'est une classe différente.  :lol: (Builder travaille comme ça...)


 
 :heink: Ca n'a rien de comique, c'est comme ça qu'on programme proprement.
 
Tu devrais lire au moins un tutorial pour débuter le C++ et apprendre la syntaxe de base sinon tu ne vas jamais y arriver.
 


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 03-05-2003 à 20:58:21   

Reply

Marsh Posté le 04-05-2003 à 01:26:51    

En fait j'ai lu beaucoup de tutos, et là j'ai emprunté deux bouquins sur le C++, donc j'ai compris beaucoup de choses, qui il est vrai doivent vous sembler bien triviales...
 
En ce qui concerne les pointeurs, je pense avoir compris l'essentiel et j'arrive à m'en sortir sans problème. Mais, et certainement que je ne t'apprends rien :) , Builder fonctionne comme ça:
 
Si je veux accéder depuis une fiche à une variable coucou qui se trouve dans MainForm, je fais

Code :
  1. MainForm->coucou

, ce qui correspond à

Code :
  1. (*MainForm).coucou

.
 
Si je veux créer un pointeur de cette variable, je fais

Code :
  1. AnsiString *pcoucou = &MainForm->coucou;

, et là quand je modifie

Code :
  1. *pcoucou

je modifie bien

Code :
  1. MainForm->coucou

.
 
Mais là avec mon problème c'est un tableau, et j'ai beau essayer plein de trucs différents, ça fonctionne pas.
 
Alors si tu pouvais m'expliquer comment déclarer ce put*** de tableau correctement dans MainForm (.h et .cpp) ainsi que la manière de déclarer dans mon autre fiche un pointeur sur ce tableau pour que je puisse utiliser les valeurs qu'il contient, tu m'aiderais vachement...
 
Merci!


Message édité par haazheel le 04-05-2003 à 01:28:02
Reply

Marsh Posté le 04-05-2003 à 05:10:51    

Tetragrammaton IHVH a écrit :


* TableauStats[] est à utiliser quand tu déclares la variable pas pour l'initialiser


 
 
Oui ...
 
Quand tu files ton tableau statique (entre accolades), tu ne peux le donner qu'au moment de la déclaration de la variable, et dans ce cas là, tu n'as pas besoin de spécifier la taille du tab dans la déclaration.
exemple :

Code :
  1. int toto[]={0,1,2,3,4};


te fera untableau de 5 ints. Par contre,

Code :
  1. int toto[5];
  2. toto={0,1,2,3,4};


ne fonctionnera pas


---------------
last.fm
Reply

Marsh Posté le 04-05-2003 à 21:26:52    

theShOcKwAvE a écrit :


Par contre,

Code :
  1. int toto[5];
  2. toto={0,1,2,3,4};


ne fonctionnera pas


 
Ca veut donc dire que dans le .h je mets sous la ligne public:

Code :
  1. int toto[5];


 
et pour remplir mon tableau dans le .cpp, je dois le remplir ligne par ligne?

Code :
  1. toto[0] = 0;
  2. toto[1] = 1;
  3. ...


 
C'est bien ça?
 
Si oui, ya pas moyen de déclarer en public directement le tableau avec tout ce qu'il contient?

Reply

Marsh Posté le 04-05-2003 à 23:23:02    

tu peux ... mais effectivement, c'est une solution à éviter ...
 
tu peux aussi déclarer tes tableaux en static const à l'extérieur de ta classe :

Code :
  1. const static int _toto[]={0,1,2,3,4};
  2. class maclasse {
  3. ...
  4. };


 
et utiliser ensuite ce tableau dans ton code ... Ca dépend de ce que tu comptes en faire
et après ca, tu dois pouvoir faire une variable toto dans ta classe que tu feras pointer au constructeur sur un tableau statique ou un autre exemple :
 

Code :
  1. // Dans ta classe :
  2. // ...
  3. protected:
  4.   int *toto;
  5. // ...
  6. // Dans ton constructeur :
  7. // ...
  8.   toto = (int *)_toto;
  9. // ...


---------------
last.fm
Reply

Marsh Posté le 05-05-2003 à 00:55:10    

Merci beaucoup, ça fonctionne maintenant... ouf...
 
Mais il subsiste encore un problème.
 
Tout d'abord, voici ce que j'ai fait:
 
En dehors de la classe:
 

Code :
  1. const static AnsiString ListeStats[] = { "LFL", "LFR", "T2L", "T2R", "T3L",
  2. "T3R", "RD", "RO", "PD", "INT", "CON", "FP", "FC", "BP" };


 
Dans le constructeur:
 

Code :
  1. pListeStats = (AnsiString *)ListeStats;


 
Et dans le .h
 

Code :
  1. AnsiString *pListeStats;


 
Dans mon autre classe:
 

Code :
  1. AnsiString *ppListeStats = MainForm->pListeStats;


 
Comme ça j'accède aux données de ListeStats[] grâce au pointeur ppListeStats.
 
Question: grâce à cette méthode, je base mon code sur un pointeur de pointeur...
Ya pas moyen d'en enlever un?
 
Sinon le problème:
 
Dans une boucle for() qui parcourt les différents éléments du tableau, je dois récupérer la taille du tableau. Je fais donc:
 

Code :
  1. for (int j=0; j<ARRAYSIZE(ppListeStats); j++)


 
Le problème est que je n'arrive pas à récupérer le nombre d'éléments contenus dans ce tableau grâce à la macro ARRAYSIZE (dans la doc de C++ Builder, ils disent qu'elle correspond à sizeof(ListeStats)/sizeof(ListeStats[0]) ), car la macro se base sur le pointeur et non pas sur le tableau original, c'est bien ça?
 
Dans ce cas, comment dois-je faire?
 
Déclarer hors classe le nombre d'éléments du tableau, comme je l'ai fait pour la déclaration du tableau?
 
Merci d'avance!!

Reply

Marsh Posté le 05-05-2003 à 09:56:31    

haazheel a écrit :


Dans mon autre classe:
 

Code :
  1. AnsiString *ppListeStats = MainForm->pListeStats;


 
Comme ça j'accède aux données de ListeStats[] grâce au pointeur ppListeStats.
 
Question: grâce à cette méthode, je base mon code sur un pointeur de pointeur...
Ya pas moyen d'en enlever un?


 
T'énerve pas : tu n'as toujours qu'un seul niveau d'indirection (ca reste un pointeur d'AnsiString et pas un pointeur de pointeur, sinon, ce serait un AnsiString **ppListeStats et tu ne pourrais pas l'utiliser directement comme un tableau)
 
Edit : précision : tu n'as fait que copier la pseudo adresse pointée dans ton autre variable ... pour récupérer l'adresse de ton pointeur (et faire un pointeur de pointeur, ici) il te faudrait utiliser le symbole '&' ...
 
 

haazheel a écrit :


 
Sinon le problème:
 
Dans une boucle for() qui parcourt les différents éléments du tableau, je dois récupérer la taille du tableau. Je fais donc:
 

Code :
  1. for (int j=0; j<ARRAYSIZE(ppListeStats); j++)


 
Le problème est que je n'arrive pas à récupérer le nombre d'éléments contenus dans ce tableau grâce à la macro ARRAYSIZE (dans la doc de C++ Builder, ils disent qu'elle correspond à sizeof(ListeStats)/sizeof(ListeStats[0]) ), car la macro se base sur le pointeur et non pas sur le tableau original, c'est bien ça?
 
Dans ce cas, comment dois-je faire?
 
Déclarer hors classe le nombre d'éléments du tableau, comme je l'ai fait pour la déclaration du tableau?
 
Merci d'avance!!


 
Oui, effectivement, c'est un problème qui apparait ici ... Ce n'est plus un tableau, donc un simple sizeof ne suffit pas à récupérer le nb d'éléments ... (je ne sais pas si il est possible de récupérer la taille mémoire allouée pour un pointeur)
Mais effectivement, dans ton cas, ce n'est pas nécessaire : tu n'as qu'à faire un joli

Code :
  1. const static int _totoSize = 5;


 
en dehors de ta classe et utiliser cette valeur ensuite ...


Message édité par theshockwave le 05-05-2003 à 09:57:57

---------------
last.fm
Reply

Marsh Posté le 05-05-2003 à 13:46:49    

theShOcKwAvE a écrit :


 
T'énerve pas : tu n'as toujours qu'un seul niveau d'indirection (ca reste un pointeur d'AnsiString et pas un pointeur de pointeur, sinon, ce serait un AnsiString **ppListeStats et tu ne pourrais pas l'utiliser directement comme un tableau)


 
Je m'énerve pas ;) , je voulais juste savoir :)
 
Merci pour ton aide précieuse...
 
A bientôt!

Reply

Marsh Posté le 05-05-2003 à 14:02:25    

haazheel a écrit :


 
En ce qui concerne les pointeurs, je pense avoir compris l'essentiel et j'arrive à m'en sortir sans problème. Mais, et certainement que je ne t'apprends rien :) , Builder fonctionne comme ça:
 


 
Arrête le chichon au lever du lit, c'est pas Builder qui fonctionne comme ça, c'est la syntaxe du C++ :lol:


Message édité par Tetragrammaton IHVH le 05-05-2003 à 14:02:48

---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 05-05-2003 à 16:34:45    

Tetragrammaton IHVH a écrit :


 
Arrête le chichon au lever du lit, c'est pas Builder qui fonctionne comme ça, c'est la syntaxe du C++ :lol:


 
:heink: Je n'irais peut-être pas jusque là ... :D
C'est clair que c'est nettement plus facile à relire qd toutes les classes sont séparées, mais il me semble que tu reste standard en collant plusieurs classes dans un même fichier ...


---------------
last.fm
Reply

Marsh Posté le 06-05-2003 à 00:46:14    

Bon en fait oui je débute en C++ (mais bon ça inutile de vous le dire, vous l'aviez sans doute remarqué... :D )
 
J'ai directement commencé à programmer avec Builder, sans avoir su au préalable ce qu'étaient une classe, l'encapsulation, les variables statiques...
 
Ce n'est que récemment que je me suis plongé dans un bouquin sur le C++ et que j'ai découvert tout ça, ainsi que la manière dont Builder fonctionne...
 
Alors oui, ça a été nouveau d'apprendre que chaque fichier correspondait à une classe, etc...
 
Donc voilà.
 
Sinon j'ai d'autres questions:
 
j'ai bien défini mes variables statiques en dehors d'une classe comme cela m'a été montré:
 

Code :
  1. const static AnsiString ListeStats[] = { "LFL", "LFR", "T2L", "T2R", "T3L",
  2. "T3R", "RD", "RO", "PD", "INT", "CON", "FP", "FC", "BP" };
  3. const static int NbreStats = ARRAYSIZE(ListeStats);


 
Dans le constructeur, je crée mes pointeurs:
 

Code :
  1. pListeStats = (AnsiString *)ListeStats;
  2. pNbreStats = (int *)NbreStats;


 
Et dans une classe où j'en ai besoin, je fais:
 

Code :
  1. int ppNbreStats = (int)MainForm->pNbreStats;
  2. AnsiString *ppListeNomStats = (AnsiString *)MainForm->pListeNomStats;


 
et donc j'y accède grâce à:
 

Code :
  1. ppNbreStats
  2. ppListeNomStats[]


 
Première question:
 
est-ce parce que ppListeNomStats pointe sur un tableau que les déclarations sont différentes?
 
Deuxième question:
 
je déclare un tableau dans une fonction membre d'une classe, et je voudrais que le tableau ait ppNbreStats éléments...
Mais à la compilation il me marque l'erreur suivante:
 
Expression constante nécessaire
 
je suis bien d'accord, mais ppNbreStats pointe justement sur NbreStats, déclaré en tant que const static...
 
Je dois alors passer par une étape intermédiaire:
 

Code :
  1. int TailleTableau = *ppNbreStats;
  2. int TableauValeurs[TailleTableau] = { 0 };


 
Je n'ai pas le choix?
 
Merci d'avance


Message édité par haazheel le 06-05-2003 à 00:51:26
Reply

Marsh Posté le 06-05-2003 à 09:03:52    

theShOcKwAvE a écrit :


 
:heink: Je n'irais peut-être pas jusque là ... :D
C'est clair que c'est nettement plus facile à relire qd toutes les classes sont séparées, mais il me semble que tu reste standard en collant plusieurs classes dans un même fichier ...


a priori oui, puisque la compilation (le préprocesseur, si je dis pas de conneries => arretez/corrigez-moi dans le cas contraire...:D) concatenera tous tes fichiers, au final (ca sert à ça les #include...)!
Par contre c'est sûr que c'est bcp plus lisible dès qu'un projet contient plusieurs classes un peu complexes...Perso ca m'arrive déjà de pas m'y retrouver facilement dans un .cpp de plusieurs milliers de lignes ne concernant qu'une classe, alors avec plusieurs classes par fichiers...:sweat:

Reply

Marsh Posté le 06-05-2003 à 09:08:51    

haazheel a écrit :

Première question:
 
est-ce parce que ppListeNomStats pointe sur un tableau que les déclarations sont différentes?


 
Oui.
 

Citation :


Deuxième question:
 
je déclare un tableau dans une fonction membre d'une classe, et je voudrais que le tableau ait ppNbreStats éléments...
Mais à la compilation il me marque l'erreur suivante:
 
Expression constante nécessaire
 
je suis bien d'accord, mais ppNbreStats pointe justement sur NbreStats, déclaré en tant que const static...
 
Je dois alors passer par une étape intermédiaire:
 

Code :
  1. int TailleTableau = *ppNbreStats;
  2. int TableauValeurs[TailleTableau] = { 0 };


 
Je n'ai pas le choix?
 
Merci d'avance


Code :
  1. int * TableauValeurs = new int[ppNbreStats];


devrait fonctionner, non?
D'ailleurs je comprends pas pkoi tu mets *ppNbreStats dans ta variable TailleTableau, et pas ppNbreStats?
Il y a un truc que j'ai pas vu/pas compris?

Reply

Marsh Posté le 06-05-2003 à 10:29:25    

skeye a écrit :


D'ailleurs je comprends pas pkoi tu mets *ppNbreStats dans ta variable TailleTableau, et pas ppNbreStats?
Il y a un truc que j'ai pas vu/pas compris?


 
Tu as raison, erreur de frappe en recopiant mon code dans la réponse :pfff: désolé
 
Quant à

Code :
  1. int * TableauValeurs = new int[ppNbreStats];


 
effectivement ça marche.
Mais quelle est la meilleure solution entre celle que tu viens de me donner, qui m'oblige à initialiser tous les éléments du tableau grâce à:

Code :
  1. for (int i=0; i < ppNbreStats; i++)
  2.         TableauValeurs[i] = 0;


 
et celle que j'avais proposé avant, à savoir:
 

Code :
  1. int NombreElements = ppNbreStats;
  2. int TableauValeurs[NombreElements] = { 0 };


 
 :??:  :??:

Reply

Marsh Posté le 06-05-2003 à 10:35:16    

skeye a écrit :


 

Code :
  1. int * TableauValeurs = new int[ppNbreStats];


devrait fonctionner, non?
D'ailleurs je comprends pas pkoi tu mets *ppNbreStats dans ta variable TailleTableau, et pas ppNbreStats?
Il y a un truc que j'ai pas vu/pas compris?


 
Disons qu'il veut utiliser un tableau statique, apparamment ... C'est à dire que les valeurs sont fixées à l'avance et aucune ne sera ajoutée par la suite vraisemblablement, ca ne requiert donc pas une alloc dynamique ...
 
Haazheel, ca, ca ne marchera pas :

Code :
  1. pListeStats = (AnsiString *)ListeStats;
  2. pNbreStats = (int *)NbreStats;

 
 
tu as quelques lacunes avec les pointeurs, toi, non ? :D

Code :
  1. pListeStats = (AnsiString *)ListeStats;
  2. pNbreStats = NbreStats;


 
Pas besoin de caster (transtyper si tu préfères) la taille de tableau en pointeur sur entier ... Tu laisses pNbreStats en tant que int pas d'* !
Remarque : tu peux directement utiliser NbreStats dans ton code ... Le const static ne doit pas te faire peur ...
 

Code :
  1. int TailleTableau = *ppNbreStats;
  2. int TableauValeurs[TailleTableau] = { 0 };

 
pareil ici ... ca ne passera pas ...
 

Code :
  1. int TailleTableau = ppNbreStats; // A la limite ...
  2. // mais ce n'est pas nécessaire de passer par une autre variable
  3. int TableauValeurs[TailleTableau] = 0;// { 0 };

 
Si tu mets des accolades, c'est que tu déclares un nouveau tableau statique dans lequel tu mets une seul valeur : 0.
 
Ensuite, tu as encore une autre erreur (:D) TableauValeurs[TailleTableau] est à l'exterieur du tableau ...
 
Rappels :
 
les indices des tableaux vont de 0 à tailletab-1 !
 
const : déclarer ta variable comme constante. Dans ce cas là, tu ne peux lui donner une valeur qu'à l'initialisation. Après, c'est fini, tu ne pourras plus la changer. (ca permet au compilo d'effectuer des optimisations comme sur les #define du C ...).
Ca peut aussi être utilisé dans les prototypes de contions/méthodes, auquel cas, il ne s'agit que d'une indication pour la relecture et d'un garde-fou pour le développeur (pas d'optimisations dans ce cas là)
 
static : limite la portée de ta variable au fichier en cours ... Ca évite qu'on y touche depuis l'extérieur de ta classe ... De plus, toutes les instances de ta classe pourront utiliser ces varriables ... (je ne saurais pas donner d'explications, mais les variables statiques qui sont déclarées dans un .h sont aussi accessibles dans le .cpp qui accompagne)
 


---------------
last.fm
Reply

Marsh Posté le 06-05-2003 à 19:24:23    

theShOcKwAvE a écrit :


Code :
  1. pListeStats = (AnsiString *)ListeStats;
  2. pNbreStats = (int *)NbreStats;

 
 
tu as quelques lacunes avec les pointeurs, toi, non ? :D

Code :
  1. pListeStats = (AnsiString *)ListeStats;
  2. pNbreStats = NbreStats;




 
Ca se voit tant que ça?  :D  
 
Bon alors effectivement j'ai essayé, et pas besoin de passer un pointeur pour mon entier NbreStats...
Alors dans mon cas, les pointeurs se limitent juste à faire passer les tableaux d'une classe à une autre?
 
Et sur des variables comme AnsiString, int... bref pas sur des tableaux, on peut se passer des pointeurs pour passer les valeurs de classe en classe? (Juste Classe->Variable)
 

Citation :

Code :
  1. int TailleTableau = *ppNbreStats;
  2. int TableauValeurs[TailleTableau] = { 0 };

 
pareil ici ... ca ne passera pas ...
 

Code :
  1. int TailleTableau = ppNbreStats; // A la limite ...
  2. // mais ce n'est pas nécessaire de passer par une autre variable
  3. int TableauValeurs[TailleTableau] = 0;// { 0 };

 
Si tu mets des accolades, c'est que tu déclares un nouveau tableau statique dans lequel tu mets une seul valeur : 0.
 
Ensuite, tu as encore une autre erreur (:D) TableauValeurs[TailleTableau] est à l'exterieur du tableau


 
Ben là c'est effectivement ce que je veux faire: créer un tableau de ppNbreStats éléments valant tous '0', que mon code suivant remplit élément par élément au fur et à mesure.
 
Mais ya un problème (encore :D )
 
Dans ma fiche principale (MainForm),je déclare NbreStats en const static à l'extérieur de la classe

Code :
  1. const static int NbreStats = ARRAYSIZE(ListeStats);


, et j'ai aussi dans le constructeur:

Code :
  1. pNbreStats = NbreStats


 
Je fais ça car je déclare pNbreStats en public pour pouvoir y accéder depuis d'autres classes.
 
Dans une autre classe:

Code :
  1. int ppNbreStats = MainForm->pNbreStats;


 
J'ai testé, et ppNbreStats renvoie bien 14.
 
Mais dans la déclaration du tableau:

Code :
  1. int TableauValeurs[ppNbreStats] = { 0 };


 
J'ai une erreur à la compilation me disant qu'il me faut une valeur constante à la place de ppNbreStats...
 
Je dois faire comment?

Reply

Marsh Posté le 07-05-2003 à 01:01:32    

haazheel a écrit :


Ca se voit tant que ça?  :D  


Naaaan ... :D Trouve toi un cours au plus vite là-dessus .... :D C'est pas compliqué, mais j'ai l'impression que tu n'as pas saisi l'utilité et que tu essayes de les mettres à toutes les sauces.
 
Fait aussi attention à l'appellation de tes variables ! en général, on part du principe que les p en début de variable indiquent des pointeurs !
 
 

haazheel a écrit :


Bon alors effectivement j'ai essayé, et pas besoin de passer un pointeur pour mon entier NbreStats...
Alors dans mon cas, les pointeurs se limitent juste à faire passer les tableaux d'une classe à une autre?


 
Là, c'est même encore plus simple : tu te sers d'un pointeur pour que ta classe sache où aller chercher le tableau ...
 
Là, la version que je t'ai donnée est pratique si tu dois choisir par exemple entre 2 tableaux que tu peux définir à l'avance ... Si il n'y en a qu'un seul, ne cherche même pas à utiliser des pointeurs ! Utilise directement ta variable (celle qui est en static const)
Le tableau est déjà partagé par toutes les instances de la classe (une zone mémoire à laquelles toutes accéderont)
 

haazheel a écrit :


Et sur des variables comme AnsiString, int... bref pas sur des tableaux, on peut se passer des pointeurs pour passer les valeurs de classe en classe? (Juste Classe->Variable)


 
:heink: Je ne vois pas ce que tu veux dire par là ...
 
syntaxe et utilisation des pointeurs (version brève et allégée ! :D) (remplace int par ce que tu veux ! :D)

Code :
  1. int *piValeur = NULL; // Pointeur sur un int, déclaration + initialisation à NULL (0 quoi ...)
  2. piValeur = new int; // Allouer de la mémoire et faire pour que le pointeur vise cette nouvelle zone mémoire
  3. piValeur* = 1; // affecter une valeur à la zone mémoire précédemment allouée
  4. delete piValeur; // libérer la mémoire allouée précédemment


même chose pour faire un tableau dynamique : cette fois-ci, tu n'alloues plus la mem pour un seul int, mais pour plusieurs :

Code :
  1. int *piValeurs = NULL; //
  2. piValeur = new int[20]; // Allouer la mem pour 20 ints ...
  3. piValeur* = 1; // Affecter 1 à la première valeur du tableau (revient grossièrement à faire piValeur[0] = 1)
  4. delete[] piValeur; // libérer le tableau alloué précédemment


 
Ne jamais oublier les delete !
 
Seulement dans le cas d'une allocation dynamique (new), tu peux utiliser une variable pour déterminer la taille de ton tableau, sinon, tu dois utiliser une expression évaluable à la compilation (une constante quoi ...). Si tu utilises directement la valeur que tu as déclaré en static const, ca passera car elle est évaluable au moment de la compilation.
 

haazheel a écrit :


Ben là c'est effectivement ce que je veux faire: créer un tableau de ppNbreStats éléments valant tous '0', que mon code suivant remplit élément par élément au fur et à mesure.


 
Dans ce cas, passe par le new dont je t'ai donné la syntaxe plus haut ...
 

haazheel a écrit :


Mais ya un problème (encore :D )


 
Et meeerde ! :D
 

haazheel a écrit :


J'ai une erreur à la compilation me disant qu'il me faut une valeur constante à la place de ppNbreStats...
 
Je dois faire comment?


 
cf ce que je t'ai dit plus haut ... Alloc dynamique si tu ne connais pas la taille à l'avance ... Sinon, tableaux statiques ...
Problème avec l'allocation dynamique : tu ne peux pas initialiser si facilement tes valeurs ... Tu dois faire une boucle (attention ... 0 à N-1 éléments) pour remplir ton tableau !
 
voilà voilà ... En espérant que ca t'aie bien aidé ! :D (ca progresse, là !)


---------------
last.fm
Reply

Marsh Posté le 07-05-2003 à 02:09:20    

Décidément, je pensais pas que tu pourrais répondre avec des posts aussi longs que mes questions... :D  
 
Effectivement, tout ce que tu m'as dis jusqu'à présent m'a beaucoup aidé...
 
Néanmoins il reste encore des points obscurs... (eh oui, désolé :D  ;) )
 
1) La notion de pointeur sur un int. Je vois pas ce que ça veut dire.
 
Pour moi un pointeur pointe sur une variable, un objet dont on veut connaître l'adresse mémoire, ce qui, dans le cas d'un objet pointé volumineux, permet de ne pas surcharger la pile...
 
2) Tu dis que les tableaux que j'ai déclaré en static const sont accessibles depuis n'importe quelle instance de la classe... Hors je veux y accéder depuis d'autres classes... Je suis donc obligé de créer un pointeur que je place en public dans la déclaration de ma classe, afin que mes autres classes puissent également y accéder, non?
 
3) Qu'est-ce que ça veut dire une "expression évaluable à la compilation"?
 
4) Dans mon dernier problème, même si je connais la taille du tableau à l'avance (elle est égale à la taille de l'un des 3 tableaux définis en const int, soit 14 pour le moment), pour créer ce tableau, je suis obligé de passer par une allocation dynamique, parce que je ne peux pas marquer ça, à cause de cette fameuse expression évaluable à la compilation:

Code :
  1. int TableauValeurs[NbreValeurs] = { 0 };


 
Donc je dois procéder de la sorte:

Code :
  1. int NbreValeurs = MainForm->pNbreStats;
  2. int* TableauValeurs = new int[NbreValeurs];
  3. for (int i=0; i < NbreValeurs-1; i++)
  4.         TableauValeurs[i] = 0;


 
c'est bien ça?  

Reply

Marsh Posté le 07-05-2003 à 09:29:31    

haazheel a écrit :


2) Tu dis que les tableaux que j'ai déclaré en static const sont accessibles depuis n'importe quelle instance de la classe... Hors je veux y accéder depuis d'autres classes... Je suis donc obligé de créer un pointeur que je place en public dans la déclaration de ma classe, afin que mes autres classes puissent également y accéder, non?


Clairement une application de la méthodologie objet bien comprise :whistle:  
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-05-2003 à 18:23:28    

gilou a écrit :


Clairement une application de la méthodologie objet bien comprise :whistle:  
A+,


 
Ce qui veut dire? :??:

Reply

Marsh Posté le 07-05-2003 à 18:35:01    

haazheel a écrit :


 
Ce qui veut dire? :??:  


Que peut etre que des accesseurs/manipulateurs, dans ta classe, et publics, ca serait plus judicieux...
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-05-2003 à 20:10:40    

haazheel a écrit :

Décidément, je pensais pas que tu pourrais répondre avec des posts aussi longs que mes questions... :D  


Je demande vérification et prétend au titre de posteur du plus long message sur ce thread ! :D Une mesure en pixels serait bienvenue ...
 

haazheel a écrit :


1) La notion de pointeur sur un int. Je vois pas ce que ça veut dire.
 
Pour moi un pointeur pointe sur une variable, un objet dont on veut connaître l'adresse mémoire, ce qui, dans le cas d'un objet pointé volumineux, permet de ne pas surcharger la pile...


 
J'ai pris l'exemple des int, parceque c'est un type archi-connu et assez simple ... 4 octets qui représentent une valeur entière signée ...
 
Utiliser un pointeur ne permet pas d'éviter une surcharge de la pile ... Une allocation dynamique le permet ! C'est totalement différent : tu peux très bien faire un pointeur sur une donnée dans la pile !
 
 

haazheel a écrit :


2) Tu dis que les tableaux que j'ai déclaré en static const sont accessibles depuis n'importe quelle instance de la classe... Hors je veux y accéder depuis d'autres classes... Je suis donc obligé de créer un pointeur que je place en public dans la déclaration de ma classe, afin que mes autres classes puissent également y accéder, non?


 
Technique 1 : tu vires le static ... Ton tableau sera accessible à toute classe qui inclut ton header .... Bon ... C'est pas forcément très recommandable
Technique 2 (recommendée) : tu crées un accesseur :
 

Code :
  1. const static int toto[] = {0, 1, 2, 3, 4};
  2. // ...
  3. class maclasse {
  4. // ...
  5.   static inline int* getToto() {return (int *)Toto;};
  6. // ...
  7. };


(le inline est là pour optimiser un peu ... et le static pour préciser qu'on n'a pas besoin de créer une instance de la classe pour accéder au tableau)
 
 

haazheel a écrit :


3) Qu'est-ce que ça veut dire une "expression évaluable à la compilation"?


Euuh ... Toute expression que tu pourrais calculer à la main et que tu as eu la flemme de faire sera calculée par le compilateur ...
 
Exemple : tu peux déclarer un tableau en faisant : int toto[2*3+1]; Ca marche ... 2*3+1 est interprété directement comme 6 à la compilation.
Il va de soi que les expressions évaluables ne se bornent pas simplement aux expressions aussi lisibles que celles-ci ... Ca peut très bien passer par l'utilisation de macros et constantes diverses voir même des résultats de fonctions templates !
Par contre, les évaluations de fonctions / méthodes, même si elles sont static inline ou autre ne sont pas acceptées ...
 

haazheel a écrit :


4) Dans mon dernier problème, même si je connais la taille du tableau à l'avance (elle est égale à la taille de l'un des 3 tableaux définis en const int, soit 14 pour le moment), pour créer ce tableau, je suis obligé de passer par une allocation dynamique, parce que je ne peux pas marquer ça, à cause de cette fameuse expression évaluable à la compilation:

Code :
  1. int TableauValeurs[NbreValeurs] = { 0 };


 
Donc je dois procéder de la sorte:

Code :
  1. int NbreValeurs = MainForm->pNbreStats;
  2. int* TableauValeurs = new int[NbreValeurs];
  3. for (int i=0; i < NbreValeurs-1; i++)
  4.         TableauValeurs[i] = 0;


 
c'est bien ça?  


 
Ben ... il faut utiliser la constante qui définit la taille de ton tableau directement ... Donc là, il vaudrait mieux que tu la rendes directement accessible en virant le static devant ta var ... Comme il s'agit d'une constante elle-même évaluable à la compilation, tu pourras l'utiliser directement pour créer ton tableau statique ... (pour garder un peu de cohérence dans tes variables, tu préfereras peut-être aussi virer le static devant ton tableau ....)
 
edit : un peu de typo ... :D


Message édité par theshockwave le 07-05-2003 à 20:13:08

---------------
last.fm
Reply

Marsh Posté le 08-05-2003 à 02:03:00    

Bon, ben ça commence à devenir bon cette histoire là...
 
Maintenant, c'est gilou qui m'a inspiré pour la prochaine question:
 
il dit qu'il vaut mieux passer par des accesseurs, que par ma méthode...
 
Ce que je fais (pour un seul tableau):
 
Hors de la classe:

Code :
  1. const static AnsiString ListeStats[] = { "LFL", "LFR", "T2L", "T2R", "T3L",
  2. "T3R", "RD", "RO", "PD", "INT", "CON", "FP", "FC", "BP" };


 
Dans la classe, en public:

Code :
  1. AnsiString *pListeStats = (AnsiString *)ListeStats;


 
Et après, dans les autres classes qui ont recours à ListeStats,:

Code :
  1. AnsiString *ppListeStats = MainForm->pListeStats;


 
Et j'utilise ppListeStats comme si j'utilisais ListeStats...
 
Bon, maintenant avec un accesseur:
 
Hors de la classe:

Code :
  1. const static AnsiString ListeStats[] = { "LFL", "LFR", "T2L", "T2R", "T3L",
  2. "T3R", "RD", "RO", "PD", "INT", "CON", "FP", "FC", "BP" };


 
Dans la classe, en public:

Code :
  1. static inline AnsiString* getListeStats() {return (AnsiString *)ListeStats;};


 
Et donc dans les autres classes j'accède à ListeStats grâce à:

Code :
  1. MainForm->GetListeStats()


 
Laquelle de ces deux méthodes est préférable?
 
Je penche pour la deuxième :D , mais c'est pour être sûr... ;) Il me semble que c'est parce qu'il vaut mieux laisser chaque classe gérer ses variables ainsi que les entrées / sorties de ces variables elles-même plutôt que de laisser des variables disponibles comme ça... C'est ça?
 
Et donc concernant la variable constante nécessaire pour initialiser la taille d'un tableau, c'est recommandable d'enlever le static? Ou bien il vaut mieux que je passe par une allocation dynamique comme j'ai en ce moment?
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 :D Juste pour avoir le post le plus long :D

Reply

Marsh Posté le 08-05-2003 à 10:15:09    

theShOcKwAvE a écrit :


 
:heink: Je n'irais peut-être pas jusque là ... :D
C'est clair que c'est nettement plus facile à relire qd toutes les classes sont séparées, mais il me semble que tu reste standard en collant plusieurs classes dans un même fichier ...


 
puis rien n'empêche de mettre plusieurs classes dans un .cpp dans Builder.
le seul truc que tu peux pas faire c'est y mettre plusieurs forms (j'ai jamais testé ça tiens [:figti])


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 08-05-2003 à 10:19:57    

theShOcKwAvE a écrit :


 
:heink: Je n'irais peut-être pas jusque là ... :D
C'est clair que c'est nettement plus facile à relire qd toutes les classes sont séparées, mais il me semble que tu reste standard en collant plusieurs classes dans un même fichier ...


 
ben encore heureux tiens...... Tu l'appelerais comment ton fichier cpp pour les classes nested sinon ? :D

Reply

Marsh Posté le 08-05-2003 à 13:42:20    

haazheel a écrit :


Laquelle de ces deux méthodes est préférable?
 
Je penche pour la deuxième :D , mais c'est pour être sûr... ;) Il me semble que c'est parce qu'il vaut mieux laisser chaque classe gérer ses variables ainsi que les entrées / sorties de ces variables elles-même plutôt que de laisser des variables disponibles comme ça... C'est ça?


 
C'est surtout que tu laisses tout le monde changer la valeur de ton pointeur depuis l'extérieur de ta classe ... Si tu fais un accesseur, plus de risque que quelqu'un modifie la valeur : tu ne retournes pas un pointeur sur la variable que tu as dans ta classe, mais bel et bien sa valeur !
En clair, ca évite des erreurs d'utilisation de ta classe ...
 

haazheel a écrit :

Bon, ben ça  
Et donc concernant la variable constante nécessaire pour initialiser la taille d'un tableau, c'est recommandable d'enlever le static? Ou bien il vaut mieux que je passe par une allocation dynamique comme j'ai en ce moment?


Vu qu'il s'agit d'un const, le compilateur agira plus ou moins comme si il s'agissait d'un #define du C, c'est à dire qu'il remplacera les occurrences de ta variable dans ton code par sa valeur (grossièrement), donc en soi, ce n'est pas un gros problème de virer le const, c'est juste que tout le monde verra la taille de ton tableau et qu'il faudra faire attention : ca pourra peut-être masquer une erreur !
C'est pour ca qu'il est conseillé de décorer les noms de variables globales que tu fais, pour ne pas tomber sur un nom déjà utilisé et éviter que cela arrive par la suite.
Exemple de déco : NOMMCLASSE_maVar ... Ca permettra déjà d'éviter pas mal de soucis ...
 
 

haazheel a écrit :

Bon, ben ça  
 :D Juste pour avoir le post le plus long :D  


[:aless]
 
 
:D


---------------
last.fm
Reply

Marsh Posté le 08-05-2003 à 13:43:23    

chrisbk a écrit :


 
ben encore heureux tiens...... Tu l'appelerais comment ton fichier cpp pour les classes nested sinon ? :D


 
oui, effectivement, en fait, c'est même évident ... J'étais un peu fatigué ... ;)


---------------
last.fm
Reply

Marsh Posté le 08-05-2003 à 20:46:22    

chrisbk a écrit :


 
ben encore heureux tiens...... Tu l'appelerais comment ton fichier cpp pour les classes nested sinon ? :D


 
C'est quoi une classe nested?

Reply

Marsh Posté le 08-05-2003 à 20:56:21    

haazheel a écrit :


 
C'est quoi une classe nested?


 
une classe dans une classe (dans une classe)

Reply

Marsh Posté le 08-05-2003 à 23:44:06    

bon, ben fort de tout ce que j'ai appris, je me lance tout seul, et là paf, je suis pas allé bien loin ya un problème... :fou:  
 
Pour résumer:
 

Code :
  1. //--------------------------------------------
  2. __fastcall TForm1::TForm1(TComponent* Owner)
  3.         : TForm(Owner)
  4. {
  5. AnsiString toto;
  6. (AnsiString *) toto = getTableau();
  7. ShowMessage(toto[0]);
  8. }
  9. //-------------------------------------------------
  10. AnsiString* __fastcall TForm1::getTableau()
  11. {
  12. AnsiString tableau[] = { "oui", "je sais" };
  13. return (AnsiString *) tableau;
  14. }


 
ShowMessage(toto[0]); me renvoie rien, à la place de "oui"... :fou:  
 
Pourtant, il me semble que c'est la même méthode que vous m'aviez indiqué auparavant, à part les static, const et inline...
 

Code :
  1. const static int toto[] = {0, 1, 2, 3, 4};
  2. // ...  
  3. class maclasse {
  4. // ...  
  5. static inline int* getToto() {return (int *)Toto;};
  6. // ...  
  7. };


Message édité par haazheel le 08-05-2003 à 23:44:32
Reply

Marsh Posté le 09-05-2003 à 10:46:13    

haazheel a écrit :

Code :
  1. //--------------------------------------------
  2. __fastcall TForm1::TForm1(TComponent* Owner)
  3.         : TForm(Owner)
  4. {
  5. AnsiString toto; // <==== là, c'est pas bien ! ;)
  6. (AnsiString *) toto = getTableau();
  7. ShowMessage(toto[0]);
  8. }
  9. //-------------------------------------------------
  10. AnsiString* __fastcall TForm1::getTableau()
  11. {
  12. AnsiString tableau[] = { "oui", "je sais" };
  13. return (AnsiString *) tableau;
  14. }




 
AnsiString *toto; Ce serait bcp mieux ...
C'est quoi ce truc immonde que tu as fait la ligne d'en-dessous ? Tu castes la variable qui prend le retour ? C'est quoi cette horreur ? En gros, t'as dit au compilo : regarde pas mon erreur, c'est ca ? :D
 
Edit : commentaire dans le code
Edit 2 : je me demande si le tableau que tu déclares en statique dans ta fonction n'est pas libéré en sortie de fonction ...


Message édité par theshockwave le 09-05-2003 à 11:15:14

---------------
last.fm
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed