Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

initialisation et double déclaration de données static d'un objet non instancié

119 réponses
Avatar
heinquoi
Bjr,
j'ai un pb de compréhension sur ce code:

class Main
{
public:
static HINSTANCE hInstance;
static HINSTANCE hPrevInstance;
static int nCmdShow;
static int MessageLoop( void );
};

HINSTANCE Main::hInstance = 0; // ici, je devrais avoir une
erreur
HINSTANCE Main::hPrevInstance = 0; // ici, aussi

il y a une double déclaration non ?
Si quelqu'un peut m'éclairer ? Et l'objet n'est meme pas initialisé.
Cordialement
Heinquoi

10 réponses

1 2 3 4 5
Avatar
Twxs
heinquoi wrote:

Bjr,
j'ai un pb de compréhension sur ce code:

class Main
{
public:
static HINSTANCE hInstance;
static HINSTANCE hPrevInstance;
static int nCmdShow;
static int MessageLoop( void );
};

HINSTANCE Main::hInstance = 0; // ici, je devrais avoir une
erreur
HINSTANCE Main::hPrevInstance = 0; // ici, aussi

il y a une double déclaration non ?


non, c'est juste que les 2 static seront initaliés au demarrage
tu peux pas les affecter dans la classe.

Twxs

Avatar
heinquoi
"Twxs" a écrit dans le message de
news:409ac1be$0$8644$
heinquoi wrote:

Bjr,
j'ai un pb de compréhension sur ce code:

class Main
{
public:
static HINSTANCE hInstance;
static HINSTANCE hPrevInstance;
static int nCmdShow;
static int MessageLoop( void );
};

HINSTANCE Main::hInstance = 0; // ici, je devrais avoir une
erreur
HINSTANCE Main::hPrevInstance = 0; // ici, aussi

il y a une double déclaration non ?


non, c'est juste que les 2 static seront initaliés au demarrage
tu peux pas les affecter dans la classe.

Twxs
je peux donc ecrire

class Main
{
public:
static HINSTANCE hInstance = 0;
static HINSTANCE hPrevInstanc = 0;
static int nCmdShow = 0;
static int MessageLoop( void );
};

les statics dans les objets n'auront quelque soit le nbre d'instances de
l'objets qu'une seule implementation ( d'apres la MSDN) mais ont une porté
limité au fichier, or je dois modifier, et utiliser ca valeur dans un autre
fichier. Y a til une solution ?


Avatar
Fabien LE LEZ
On Fri, 7 May 2004 00:36:01 +0200, "heinquoi"
<nospam* wrote:

class Main
{
public:
static HINSTANCE hInstance; // 1
};

HINSTANCE Main::hInstance = 0; // 2

il y a une double déclaration non ?


Non.
Pour faire simple, une variable globale occupe un certain espace dans
l'exécutable (le fichier .exe).
Ainsi, si tu veux avoir une variable globale dans ton programme, tu
dois la créer dans un .cpp :

int ma_variable_globale;

et déclarer son existence dans un .h, pour que les autres modules
puissent la voir :

extern int ma_variable_globale;

Une variable membre static, c'est la même chose : tu dois la créer
dans un (un seul) .cpp :

HINSTANCE Main::hInstance;

et indiquer son existence dans un .h, et plus précisément dans la
définition de la classe :

class Main
{
public:
static HINSTANCE hInstance;
};

Eventuellement, tu peux aussi lui donner une valeur de départ
(obligatoire s'il s'agit d'une constante). Généralement, on indique
cette valeur dans le .cpp :

HINSTANCE Main::hInstance= 0;

(ou, pour la variable globale :
int ma_variable_globale= 0;
)

Pour les types entiers, toutefois, on peut mettre sa valeur dans la
déclaration de la classe -- à condition toutefois d'avoir un compilo
raisonnablement récent. Par contre, je ne sais plus si ça s'applique
seulement aux constantes, ou aussi aux variables non const.

Exemple :

// .h

class Main
{
static size_t const TAILLE_TABLEAU= 12;
unsigned tableau [TAILLE_TABLEAU];
};

// .cpp

size_t const Main::TAILLE_TABLEAU;



--
;-)
FLL, Epagneul Breton

Avatar
heinquoi
"Fabien LE LEZ" a écrit dans le message de
news:
On Fri, 7 May 2004 00:36:01 +0200, "heinquoi"
<nospam* wrote:

class Main
{
public:
static HINSTANCE hInstance; // 1
};

HINSTANCE Main::hInstance = 0; // 2

il y a une double déclaration non ?


Non.
Pour faire simple, une variable globale occupe un certain espace dans
l'exécutable (le fichier .exe).
Ainsi, si tu veux avoir une variable globale dans ton programme, tu
dois la créer dans un .cpp :

int ma_variable_globale;

et déclarer son existence dans un .h, pour que les autres modules
puissent la voir :

extern int ma_variable_globale;

Une variable membre static, c'est la même chose : tu dois la créer
dans un (un seul) .cpp :

HINSTANCE Main::hInstance;

et indiquer son existence dans un .h, et plus précisément dans la
définition de la classe :

class Main
{
public:
static HINSTANCE hInstance;
};

Eventuellement, tu peux aussi lui donner une valeur de départ
(obligatoire s'il s'agit d'une constante). Généralement, on indique
cette valeur dans le .cpp :

HINSTANCE Main::hInstance= 0;

(ou, pour la variable globale :
int ma_variable_globale= 0;
)

Pour les types entiers, toutefois, on peut mettre sa valeur dans la
déclaration de la classe -- à condition toutefois d'avoir un compilo
raisonnablement récent. Par contre, je ne sais plus si ça s'applique
seulement aux constantes, ou aussi aux variables non const.

Exemple :

// .h

class Main
{
static size_t const TAILLE_TABLEAU= 12;
unsigned tableau [TAILLE_TABLEAU];
};

// .cpp

size_t const Main::TAILLE_TABLEAU;



--
;-)
FLL, Epagneul Breton


oui, oui
Merci bcp et effectivement ca fonctionne pour moi!
je l'ai declaré ds sa class dans un hpp:
static HINSTANCE h;
, et defini dans mon .cpp => aucun probleme, compilation parfaite.

merci de ces précisions. Pour ma par je pensais ( d'apres bcp de livre ) que
static limitais le TYPE au fichier dans lequel il etait déclaré,
d'apres ma lecture
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_static.asp
.la porté d'une donnée static est reduite au fichier d'origine de la donnée
tout en etant detruite en meme temps que la fin de l'appli.
Je vois donc que suis pas a jour sur des connaissances pourtant élémentaire.
Merci, encore une fois.


Avatar
Fabien LE LEZ
N'hésite pas à faire des coupes sombres dans les citations ; si deux
lignes de citation suffisent pour faire comprendre ton message, tu
peux couper tout le reste.
En particulier, on ne cite jamais une signature.

--
;-)
FLL, Epagneul Breton
Avatar
kanze
"heinquoi" <nospam* wrote in message
news:<409abdf5$0$27678$...

j'ai un pb de compréhension sur ce code:

class Main
{
public:
static HINSTANCE hInstance;
static HINSTANCE hPrevInstance;
static int nCmdShow;
static int MessageLoop( void );
};

HINSTANCE Main::hInstance = 0; // ici, je devrais avoir une
erreur
HINSTANCE Main::hPrevInstance = 0; // ici, aussi

il y a une double déclaration non ?


Oui, mais une qui est permise.

En général, il n'y a pas de règle contre des double déclarations. Tu
peux, par exemple, écrire :

extern void f() ;
extern void f() ;
// autant de fois que tu veux.

La règle absolue, c'est contre les doubles définitions (et encore, il y
a des exceptions -- mais pas à l'intérieur d'une unité de traducion).
Mais à l'intérieur d'une classe, la declaration d'un membre statique ou
d'une fonction n'est PAS une définition. Alors, une définition ailleur
est non seulement légale, mais aussi obligatoire.

(Il y a aussi des règles contre la double declaration, dans certains
contextes, au moins. Donc, par exemple, deux déclarations de hInstance à
l'intérieur de la classe serait illégales.)

Si quelqu'un peut m'éclairer ? Et l'objet n'est meme pas initialisé.


Comment, il n'est pas initialisé ? Si Main::hInstance et
Main::hPrevInstance ne sont pas initialisés, il y a un problème grave
avec ton compilateur.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
kanze
"heinquoi" <nospam* wrote in message
news:<409ac620$0$27678$...
"Twxs" a écrit dans le message de
news:409ac1be$0$8644$
heinquoi wrote:

j'ai un pb de compréhension sur ce code:

class Main
{
public:
static HINSTANCE hInstance;
static HINSTANCE hPrevInstance;
static int nCmdShow;
static int MessageLoop( void );
};

HINSTANCE Main::hInstance = 0; // ici, je devrais avoir une
erreur
HINSTANCE Main::hPrevInstance = 0; // ici, aussi

il y a une double déclaration non ?


non, c'est juste que les 2 static seront initaliés au demarrage tu
peux pas les affecter dans la classe.


je peux donc ecrire
class Main
{
public:
static HINSTANCE hInstance = 0;
static HINSTANCE hPrevInstanc = 0;
static int nCmdShow = 0;
static int MessageLoop( void );
};


Pas en général. Il y a une règle spéciale (une exception) pour les types
entiers const, mais sinon, tu ne peux fournir une initialisation qu'à
une définition, et les declarations à l'intérieur d'une définition de
classe ne sont que des declarations, et non des définitions. (Toute
définition est aussi une declaration, mais l'inverse est loin d'être
vrai.)

les statics dans les objets n'auront quelque soit le nbre d'instances
de l'objets qu'une seule implementation ( d'apres la MSDN) mais ont
une porté limité au fichier, or je dois modifier, et utiliser ca
valeur dans un autre fichier.


Le mot clé « static » est surchargé -- sa signification dépend de
l'utilisation qu'on en fait : la portée de l'objet déclaré static, et si
c'est un objet ou une fonction. Donc, un objet ou une fonction déclaré
static à la portée de namespace (en dehors d'une définition de classe ou
de fonction) n'est visible que dans l'unité de compilation où il a été
déclaré. Un objet déclaré static dans une fonction a une durée de vie
jusqu'à la fin du programme, n'est initialisé que la première fois qu'il
entre en vue, et garde son état entre des appels à la fonction. Un objet
déclaré static dans une classe a une durée de vie de toute l'execution
du programme, existe même s'il n'y a pas d'instances de la classe, et
n'existe qu'une fois, quoique soit le nombre d'instances de la classe.
Et une fonction déclarée static dans une classe n'a pas de pointeur
this, et peut être appelée sans instance de la classe.

Y a til une solution ?


Y a-t-il un problème ?

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
heinquoi
a écrit dans le message de
news:
...
Pas en général. Il y a une règle spéciale (une exception) pour les types
entiers const, mais sinon, tu ne peux fournir une initialisation qu'à
une définition, et les declarations à l'intérieur d'une définition de
classe ne sont que des declarations, et non des définitions. (Toute
définition est aussi une declaration, mais l'inverse est loin d'être
vrai.)

les statics dans les objets n'auront quelque soit le nbre d'instances
de l'objets qu'une seule implementation ( d'apres la MSDN) mais ont
une porté limité au fichier, or je dois modifier, et utiliser ca
valeur dans un autre fichier.


Le mot clé « static » est surchargé -- sa signification dépend de
l'utilisation qu'on en fait : la portée de l'objet déclaré static, et si
c'est un objet ou une fonction. Donc, un objet ou une fonction déclaré
static à la portée de namespace (en dehors d'une définition de classe ou
de fonction) n'est visible que dans l'unité de compilation où il a été
déclaré. Un objet déclaré static dans une fonction a une durée de vie
jusqu'à la fin du programme, n'est initialisé que la première fois qu'il
entre en vue, et garde son état entre des appels à la fonction. Un objet
déclaré static dans une classe a une durée de vie de toute l'execution
du programme, existe même s'il n'y a pas d'instances de la classe, et
n'existe qu'une fois, quoique soit le nombre d'instances de la classe.
Et une fonction déclarée static dans une classe n'a pas de pointeur
this, et peut être appelée sans instance de la classe.

Y a til une solution ?


Y a-t-il un problème ?
Non, plus maintenant et grace à ta réponse et à a celle des autres posters.

Merci donc.
N'ayant trouvé aucune doc aussi clair que vos poste (meme ds "Le langage
c++" de Bjarne Stroustrup)
je vais m'en faire un copie et les conserver, si cela ne dérange pesonne.


Avatar
heinquoi
a écrit dans le message de
news:
Si quelqu'un peut m'éclairer ? Et l'objet n'est meme pas initialisé.


Comment, il n'est pas initialisé ? Si Main::hInstance et
Main::hPrevInstance ne sont pas initialisés, il y a un problème grave
avec ton compilateur.


Non, le compilateur est un intel version 8. C'est parce que ce sont des
données static, qui sont alloué dès la déclaration, mais qui, quelque soit
le nb d'instanciation de la class seront toujours unique. INTERESSANT comme
propriété. D'apres Stroustrup, cela permet d'evité d'avoir a utiliser des
données globales accessible et modifiable de partout.
mais, static etait utilisé dans le C et au début du C++ pour réduire la
porté d'une donnée à un fichier. Cette propriété à ete conservé...j'ai donc
du mal à m'y retrouver ... mais grace au différents postes ca va mieux.
Merci a tous.
Heinquoi


Avatar
kanze
"heinquoi" <nospam* wrote in message
news:<409b67ad$0$27685$...
a écrit dans le message de
news:
Si quelqu'un peut m'éclairer ? Et l'objet n'est meme pas
initialisé.


Comment, il n'est pas initialisé ? Si Main::hInstance et
Main::hPrevInstance ne sont pas initialisés, il y a un problème grave
avec ton compilateur.


Non, le compilateur est un intel version 8. C'est parce que ce sont
des données static, qui sont alloué dès la déclaration, mais qui,
quelque soit le nb d'instanciation de la class seront toujours unique.


Tout à fait. Et si tu en as écrit une initialisation (comme il avait
fait), et qu'il ne sont pas initialisé, c'est une erreur du compilateur.

INTERESSANT comme propriété. D'apres Stroustrup, cela permet d'evité
d'avoir a utiliser des données globales accessible et modifiable de
partout. mais, static etait utilisé dans le C et au début du C++ pour
réduire la porté d'une donnée à un fichier.


Static a eu plusieurs significations depuis le départ, en C. Une
variable locale static, ce n'est pas la même chose qu'une variable à la
portée du fichier static.

Au moins à une époque, il y a eu une résistance farouche contre
l'introduction des nouveaux mots clés. Alors, Stroustrup à recycler
static encore une fois, pour encore une autre signification (ou plutôt
deux significations, puisque le concepte des fonctions membre static et
des variables membre static ne sont que faiblement apparentés).

Cette propriété à ete conservé... j'ai donc du mal à m'y retrouver ...


Pas de problème. Rappelle-toi que la signification de static dépend d'où
il sert.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



1 2 3 4 5