[C++] Histoire de membres statiques

Histoire de membres statiques [C++] - C++ - Programmation

Marsh Posté le 02-02-2004 à 09:56:33    

Bonjour,
 
Concernant les membres statiques.
Quand pour un pointeur quelconque, statique, on alloue de la mémoire à l'initialisation.
Comment doit on doit libérer cette mémoire ?  
A la fin de l'appli. ?  
Je trouve cette solution risquée car elle oblige l'utilisateur de la classe à penser de libérer cette mémoire même une fois  tous les obj. libérés.
 
Sinon à quel moment est initialisé ce membre statique quand l'initialisation est placée dans le .cpp en dehors de la portée de la classe.
A la première instanciation ?
 
Merci de votre aide  

Reply

Marsh Posté le 02-02-2004 à 09:56:33   

Reply

Marsh Posté le 02-02-2004 à 13:04:19    

Citation :

Comment doit on doit libérer cette mémoire? A la fin de l'appli?


a toi de voir! Une réponse satisfaisante pourrait être: quand tu n'en a plus besoin...
 
Il faut voir une variable membre statique de la même façon qu'un variable globale en C, mais avec une restriction des droits d'accès définis pas sa définition au sein de la classe.
 

Citation :

je trouve cette solution risquée car elle oblige l'utilisateur de la classe à penser de libérer cette mémoire même une fois  tous les obj. libérés.


C'est pour cette raison que tu verras souvent une méthode statique de classe du type static void release() qui permet de désallouer les variables staiques une fois que l'on n'en a plus besoin. Mais il n'y a pas une seule et bonne réponse.
 

Citation :

Sinon à quel moment est initialisé ce membre statique quand l'initialisation est placée dans le .cpp en dehors de la portée de la classe.


pas compris la question. Qu'est-ce que tu entends par "en dehors de la portée de la classe"?
Normalement, une variable statique (membre ou pas membre) doit être déclarée une fois (et une seule) dans un fichier source. L'instancatiation se fait au chargement du module concerné (ie le lancement du programme ou le chargement d'une bibliothèque dynamique).
 

Citation :

A la première instanciation ?


cela n'a aucun sens. Une variable membre statique n'existe qu'à 1 seul exemplaire et n'est en rien attaché à une instance de la classe (et donc son constructeur). Encore une fois, il faut voir une variable membre statique comme une variable C globale avec des droits d'accès particuliers.


Message édité par SoWhatIn22 le 02-02-2004 à 13:14:33
Reply

Marsh Posté le 02-02-2004 à 15:41:23    

Citation :

Citation :
--------------------------------------------------------------------------------
Sinon à quel moment est initialisé ce membre statique quand l'initialisation est placée dans le .cpp en dehors de la portée de la classe.
--------------------------------------------------------------------------------
 
 
pas compris la question. Qu'est-ce que tu entends par "en dehors de la portée de la classe"?  
Normalement, une variable statique (membre ou pas membre) doit être déclarée une fois (et une seule) dans un fichier source. L'instancatiation se fait au chargement du module concerné (ie le lancement du programme ou le chargement d'une bibliothèque dynamique).


 
J'entendais par là initialisation de la variable à l'extérieur de la déclaration de la classe, hors de sa portée, de son "scope".
 
OK pour la libération, il faut que j'encapsule les libérations de toutes les variables statiques dans une méthode de classe.
En farfouillant sur la toile, j'ai vu que bien souvent les éléments statiques étaient encapsulés dans une classe "singleton", ce concept me semble pas mal surtout qu'une d'1 des designs patterns proposés permet, pour des implémentations simples et adaptées, de détruire les variables statiques en s'appuyant sur le destructeur implicite du language. je gagnerait donc l'appel explicite du destructeur vu précédemment.
 
Sinon tjrs concernant ces mêmes variables statiques je galère actuellement sur un problème(avec utilisation d'OpenGL).
J'hésite à passer les src car c'est un peu long. Je vais tenter d'expliquer le code brièvement :
Voilà,  
J'avais une classe CCanard avec un constructeur dans lequel je construisait une liste d'affichage pour dessiner un vilain petit canard. Pour afficher mon canard dans la scène OpenGL j'appelait tout simplement la liste d'aff. compilée , glCallList(id_canard), dans une méthode affiche. Jusque là tout allait bien.  
Mais l'emploi d'une liste d'aff. dans une telle implémentation n'avait absolument aucun intérêt, une liste étant créée à chaque instanciation alors, là où son intérêt est de conserver un cache de cdes OpenGL compilées en mémoire pour être appelées plusieurs fois, dans mon cas par plusieurs instances de la classe CCanard.
J'ai donc décidé de rendre statique la création de la liste d'affichage, ce qui m'a semblé être un bon emploi de cette fonctionnalité.
 
Je me retrouve avec
dans le .h :
 
....
private :
  static GLuint id_canard;
  static GLUquadricObj *pQuadTete;
  //+ déclarations d'autres obj. quadrics
  static GLuint creerListeAffCanard();
 
dans le .cpp :
 
GLUquadricObj *CCanard::pQuadTete = gluNewQuadric();
//+ autres initialisations des obj. quadrics
//Création de la liste d'affichage statique
GLuint CCanard::id_canard = CCanard::creerListeAffCanard();
 
 
Mais le vilain petit canard ne veut plus apparaître.
Où diable est mon canard ?
 
Ma méthode affiche n'a pratiquement pas bougé, hormis la référence à id_canard, glCallList(CCanard::id_canard).
 
J'ai placé quelques vertexes dans la méthode affiche et ils apparaissent bien dans la scène, le pb vient donc bien de ma liste d'affichage.
 
Avez vous compris quelque chose ?    
 

Reply

Marsh Posté le 02-02-2004 à 20:25:15    

je compren trop pas pourquoi tu fait ca
GLuint CCanard::id_canard = CCanard::creerListeAffCanard();  
 
dans ta fonction static creerlist, tu creer la liste en mettant au debut bien sur
glNewList(id_canard,GL_COMPILE);  
et puis c'est tout, non?

Reply

Marsh Posté le 02-02-2004 à 21:06:39    

C'est ce que j'avais codé initialement :
 
dans le .h :
 
private :
   ...  
   static GLuint id_canard;
     
   static void creerListeAffCanard();
 
dans le .cpp :
 
...
creerListeAffCanard();
...
void CCanard::creerListeAffCanard()
{
  glNewList(CCanard::id_canard = glGenLists(1), GL_COMPILE);
...
 
mais VC++ me renvoyait une erreur de liens en pleine gueule :
 
Linking...
CCanard.obj : error LNK2001: unresolved external symbol "public: static unsigned int  CCanard::id_canard" (?id_canard@CCanard@@2IA)
Debug/coincoin.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.  
 
Ma 2ème implémentation à solutionné sans que ne je sache expliquer pourquoi. Dans l'urgence je n'ai pas cherché à comprendre.
 
Peut être est ce la clé à mon pb de liste ?

Reply

Marsh Posté le 02-02-2004 à 21:21:47    

ben moi ca marche mais CCanard::id_canard  est public

Reply

Marsh Posté le 02-02-2004 à 21:56:10    

OK pour l'erreur à l'édition des liens :
 
dans le .h, rien de changé :  
private :  
  ...  
  static GLuint id_canard;    
  static void creerListeAffCanard();  
 
dans le .cpp, il faut définir et initialiser les membres statiques :  
 
...  
const GLuint CCanard::id_canard = glGenLists(1);
creerListeAffCanard();  
...  
void CCanard::creerListeAffCanard()  
{  
 glNewList(CCanard::id_canard, GL_COMPILE);  
...  
 
Je n'ai plus l'erreur à l'édition des liens.
Tu ne dois donc pas être obligé de déclarer tous tes membres statiques, publiques

Reply

Marsh Posté le 02-02-2004 à 22:04:40    

oui aussi mais pour moi c'est plus pratique en public

Reply

Sujets relatifs:

Leave a Replay

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