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

initialisation de variable static

10 réponses
Avatar
Marc G
Bonjour,
Une question bête ...

Dans la traditionnelle organisation entre fichiers hpp/cpp, quand vous
déclarez une classe avec une donnée membre static,
est-il équivalent de l'initialiser dans le fichier hpp (après déclaration de
la classe par exemple) ou dans le fichier cpp ?
Merci
Marc

10 réponses

Avatar
James Kanze
On Jul 1, 8:34 am, "Marc G" wrote:

Une question bête ...



Dans la traditionnelle organisation entre fichiers hpp/cpp,
quand vous déclarez une classe avec une donnée membre static,
est-il équivalent de l'initialiser dans le fichier hpp (après
déclaration de la classe par exemple) ou dans le fichier cpp ?



En général, tu ne peux l'initialiser que dans la définition, qui
normalement se trouve dans le fichier source (.cc, .cpp, etc.).
Dans la définition de la classe, la déclaration d'une donnée
statique n'est qu'une déclaration ; il faut encore une
définition quelque part, et l'initialisation, normalement, fait
partie de la définition, et non la déclaration.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
Marc G
merci à toi
et pour les données membres static de template ?

J'ai des classes avec une donnée membre static empty_one_,
un truc du genre

// fichier hpp

template<typename T>
class Bidule {
static Bidule empty_one_;
};
// la définition de la donnée membre static est fournie immédiatement après
la déclaration de classe,
// dans le fichier hpp donc :
template<typename T> Bidule<T> Bidule<T>::empty_one_=Bidule<T>();

Bon évidement, définition ne veut pas dire instanciation. Mais si je place
cette définition dans le fichier cpp,
je peux avoir un problème d'ordre de compilation des fichiers du programme
et mes classes (qui sont des templates) accèdent mutuellement à cette donnée
membre static.
Mon compilateur accepte sans râler cette façon de procéder...

nota : dans le livre "l'essentiel du C++ " de Stanley B. Lippman et Josée
Lajoie, je lis page 749
"les définitions des données membres statiques sont ajoutées au fichier
d'en-tête xxx" (je précise qu'il s'agit de définition des données membres
static de template !)
Marc
Avatar
Michael DOUBEZ
Marc G a écrit :
merci à toi
et pour les données membres static de template ?

J'ai des classes avec une donnée membre static empty_one_,
un truc du genre

// fichier hpp

template<typename T>
class Bidule {
static Bidule empty_one_;
};
// la définition de la donnée membre static est fournie immédiatement
après la déclaration de classe,
// dans le fichier hpp donc :
template<typename T> Bidule<T> Bidule<T>::empty_one_=Bidule<T>();



Si tu veux faire ce genre de chose, utilise plutôt une fonction static:

template<typename T>
class Bidule
{
static Bidule& empty_one_()
{
static Bidule empty_one;
return empty_one;
}
};


--
Michael
Avatar
James Kanze
On Jul 1, 9:58 am, "Marc G" wrote:
merci à toi
et pour les données membres static de template ?



C'est en principe pareil. Sauf qu'évidemment, si le template
n'est pas exporté (et la plupart des compilateurs n'implémentent
pas encore export), il faut que la définition soit présent dans
toutes les unités de compilation où elle pourrait être
instantiée :

template<class T> class X {
static T s;
};
template<class T> T X<T>::s = 0;

J'ai des classes avec une donnée membre static empty_one_, un
truc du genre



// fichier hpp

template<typename T>
class Bidule {
static Bidule empty_one_;};



// la définition de la donnée membre static est fournie immédiateme nt après
la déclaration de classe,
// dans le fichier hpp donc :
template<typename T> Bidule<T> Bidule<T>::empty_one_=Bidule<T>();



Bon évidement, définition ne veut pas dire instanciation. Mais
si je place cette définition dans le fichier cpp, je peux
avoir un problème d'ordre de compilation des fichiers du
programme et mes classes (qui sont des templates) accèdent
mutuellement à cette donnée membre static.
Mon compilateur accepte sans râler cette façon de procéder...



Certes. Mais c'est parce qu'en général, quand il s'agit d'un
template, le compilateur s'attend à trouver les définitions dans
l'unité de compilation où elles servent.

C'est pareil que pour les fonctions membres.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
James Kanze
On Jul 1, 12:02 pm, Michael DOUBEZ wrote:
Marc G a écrit :
> et pour les données membres static de template ?



> J'ai des classes avec une donnée membre static empty_one_,
> un truc du genre



> // fichier hpp



> template<typename T>
> class Bidule {
> static Bidule empty_one_;
> };
> // la définition de la donnée membre static est fournie immédiate ment
> après la déclaration de classe,
> // dans le fichier hpp donc :
> template<typename T> Bidule<T> Bidule<T>::empty_one_=Bidule<T>();



Si tu veux faire ce genre de chose, utilise plutôt une fonction static:



template<typename T>
class Bidule
{
static Bidule& empty_one_()
{
static Bidule empty_one;
return empty_one;
}
};



Ce qui risque de poser des problèmes dans un environement
multi-threaded.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
Marc G
> Ce qui risque de poser des problèmes dans un environement
multi-threaded.



juste en quelques mots (si possible), pourquoi ?
je ne programme pas en multithread :-(
Avatar
Marc G
mes excuses à James Kanze
j'ai cliqué "répondre à l'expéditeur" et pas "répondre au groupe" par erreur
sincérement désolé
Avatar
Michael DOUBEZ
Marc G a écrit :
Ce qui risque de poser des problèmes dans un environement
multi-threaded.



juste en quelques mots (si possible), pourquoi ?



Parce qu'il n'y a pas de garantie que le premier appel (et donc la
construction de la static) se fasse de façon atomique.

je ne programme pas en multithread :-(



Alors pas de problème. Je dirais que c'est bien de documenter quand même
au cas où, un jour, ce template soit réutilisé dans une application
multithreadée.

--
Michael
Avatar
Fabien LE LEZ
On Wed, 02 Jul 2008 08:51:06 +0200, Michael DOUBEZ
:

Alors pas de problème. Je dirais que c'est bien de documenter quand même
au cas où, un jour, ce template soit réutilisé dans une application
multithreadée.



Ceci serait-il une bonne idée ?

static Bidule& empty_one_()
{
#ifdef __MT__
#error Cette fonction n'est pas thread-safe !
#endif
static Bidule empty_one;
return empty_one;
}
Avatar
Michael DOUBEZ
Fabien LE LEZ a écrit :
On Wed, 02 Jul 2008 08:51:06 +0200, Michael DOUBEZ
:

Alors pas de problème. Je dirais que c'est bien de documenter quand même
au cas où, un jour, ce template soit réutilisé dans une application
multithreadée.



Ceci serait-il une bonne idée ?

static Bidule& empty_one_()
{
#ifdef __MT__
#error Cette fonction n'est pas thread-safe !
#endif
static Bidule empty_one;
return empty_one;
}



Plus les compilateur supportés :)

Pour ce genre de chose, j'ai tendance à mettre un warning ou je
documente. Ce n'est pas quelque chose de fatal, par exemple si le coder
fait attention à appeler la fonction au moins une fois avant de démarrer
le multithreading ou si c'est sans objet.

// _MT: compilateur Microsoft
// __MT__: compilateur Borland
// _PTHREADS: gcc
#if defined(_MT) || defined(__MT__) || defined(_PTHREAD)
#warning "Cette fonction n'est pas thread-safe !"
#endif

--
Michael