Bonjour,
j'ai une classe avec une présentation classique :
- déclarations dans le fichier hpp
- définitions dans le fichier cpp
je me pose la question de la différence entre une variable globale définie
comme suit :
dans cpp :
vector<std::string> x;
et la même chose en tant que membre static private d'une classe
(c'est juste une variable utilisée fréquemment dans certaines méthodes (je
programme un interpréteur))
Dans les deux cas, je ne sais pas comment l'initialiser, excepté dans le
corps du constructeur de la classe qui peut tester si la liste est vide...
Mais je trouve cette solution pas très élégante.
Je veux l'initialiser avec une liste de mots.
est-ce que je peux écrire simplement dans le fichier cpp.
vector<std::string> x;
x.push_back("mot1");
x.push_back("mot2");
etc...
Dans ce cas, quand ce bout de code est exécuté ? (je me pose cette question
parce que ça marche avec mon compilateur, mais que ça me paraît dangeureux
!)
je me pose la question de la différence entre une variable globale définie comme suit : dans cpp : vector<std::string> x; et la même chose en tant que membre static private d'une classe (c'est juste une variable utilisée fréquemment dans certaines méthodes (je programme un interpréteur))
Dans les deux cas, je ne sais pas comment l'initialiser, excepté dans le corps du constructeur de la classe qui peut tester si la liste est vide... Mais je trouve cette solution pas très élégante. Je veux l'initialiser avec une liste de mots.
est-ce que je peux écrire simplement dans le fichier cpp. vector<std::string> x; x.push_back("mot1"); x.push_back("mot2"); etc...
Ce n'est pas légal, c'est sûrement une extension du compilateur.
Personnellement, j'utiliserais une fonction statique (modèle singleton simplifié) :
Ce qui règle le problème de l'ordre d'initialisation, mais pas l'éventuel problème de l'ordre de destruction.
-- Sylvain Togni
MGN wrote:, :
je me pose la question de la différence entre une variable globale définie
comme suit :
dans cpp :
vector<std::string> x;
et la même chose en tant que membre static private d'une classe
(c'est juste une variable utilisée fréquemment dans certaines méthodes (je
programme un interpréteur))
Dans les deux cas, je ne sais pas comment l'initialiser, excepté dans le
corps du constructeur de la classe qui peut tester si la liste est vide...
Mais je trouve cette solution pas très élégante.
Je veux l'initialiser avec une liste de mots.
est-ce que je peux écrire simplement dans le fichier cpp.
vector<std::string> x;
x.push_back("mot1");
x.push_back("mot2");
etc...
Ce n'est pas légal, c'est sûrement une extension du compilateur.
Personnellement, j'utiliserais une fonction statique (modèle
singleton simplifié) :
je me pose la question de la différence entre une variable globale définie comme suit : dans cpp : vector<std::string> x; et la même chose en tant que membre static private d'une classe (c'est juste une variable utilisée fréquemment dans certaines méthodes (je programme un interpréteur))
Dans les deux cas, je ne sais pas comment l'initialiser, excepté dans le corps du constructeur de la classe qui peut tester si la liste est vide... Mais je trouve cette solution pas très élégante. Je veux l'initialiser avec une liste de mots.
est-ce que je peux écrire simplement dans le fichier cpp. vector<std::string> x; x.push_back("mot1"); x.push_back("mot2"); etc...
Ce n'est pas légal, c'est sûrement une extension du compilateur.
Personnellement, j'utiliserais une fonction statique (modèle singleton simplifié) :
Mais maintenant, il y aurat remplissage (ajout) du tableau a chaque appel de getX, ca va vite devenir un probleme. Il faudrait au moins ceci pour un comportement correct:
Mais maintenant, il y aurat remplissage (ajout) du tableau a chaque
appel de getX, ca va vite devenir un probleme. Il faudrait au moins
ceci pour un comportement correct:
Mais maintenant, il y aurat remplissage (ajout) du tableau a chaque appel de getX, ca va vite devenir un probleme. Il faudrait au moins ceci pour un comportement correct:
j'ai une classe avec une présentation classique : - déclarations dans le fichier hpp - définitions dans le fichier cpp
je me pose la question de la différence entre une variable globale définie comme suit : dans cpp : vector<std::string> x;
C'est une définition de la variable (avec initialisation par le constructeur par défaut).
et la même chose en tant que membre static private d'une classe (c'est juste une variable utilisée fréquemment dans certaines méthodes (je programme un interpréteur))
C'est à peu près pareil. Quand il s'agit des membres statiques, ce qu'il y a dans la classe, c'est une declaration, non une définition. Il faut donc une définition quelque part ailleurs (dans un cpp).
Dans les deux cas, je ne sais pas comment l'initialiser,
Comme avec n'importe quelle définition.
Donc :
class C { public: static double const f ; } ;
et dans un cpp :
double C::f = 3.14159 ;
excepté dans le corps du constructeur de la classe qui peut tester si la liste est vide... Mais je trouve cette solution pas très élégante. Je veux l'initialiser avec une liste de mots.
est-ce que je peux écrire simplement dans le fichier cpp. vector<std::string> x; x.push_back("mot1"); x.push_back("mot2"); etc...
C'est une technique utile quand l'initialisation comporte des choses qu'on ne peut pas faire avec un constructeur existant.
Dans les deux cas, attention quand même à l'ordre de l'initialisation, qui n'est pas défini entre des unités de compilation différente. Si tu t'attends à te servir de cet x dans le constructeur d'un autre objet statique, dans une autre unité de compilation, tu risques d'avoir des surprises désagréables. Dans ces cas-là (et même plus généralement, pour ne pas exclure cette éventualité à l'avenir), c'est habituel de se rabattre sur le modèle singleton.
Dans ce cas, quand ce bout de code est exécuté ? (je me pose cette question parce que ça marche avec mon compilateur, mais que ça me paraît dangeureux !)
Tel que tu l'as écrit, ça ne doit pas marcher. Tu ne peux mettre des instructions « exécutables » que dans une fonction. Sauf qu'évidemment, l'initialisation d'une variable statique peut comporter des instructions exécutable, par exemple, un constructeur, ou une expression d'initialisation qui n'est pas constante. Pour ces instructions-là, la règle veut qu'à l'intérieur d'une unité de compilation, l'ordre d'initialisation suit l'ordre des declarations, et que (dans la pratique, au moins, et dans l'absence d'une édition de liens dynamique) toutes les initialisations aient lieu avant d'entrer dans main().
-- James Kanze GABI Software 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
MGN wrote:
j'ai une classe avec une présentation classique :
- déclarations dans le fichier hpp
- définitions dans le fichier cpp
je me pose la question de la différence entre une variable
globale définie comme suit :
dans cpp :
vector<std::string> x;
C'est une définition de la variable (avec initialisation par le
constructeur par défaut).
et la même chose en tant que membre static private d'une
classe (c'est juste une variable utilisée fréquemment dans
certaines méthodes (je programme un interpréteur))
C'est à peu près pareil. Quand il s'agit des membres statiques,
ce qu'il y a dans la classe, c'est une declaration, non une
définition. Il faut donc une définition quelque part ailleurs
(dans un cpp).
Dans les deux cas, je ne sais pas comment l'initialiser,
Comme avec n'importe quelle définition.
Donc :
class C
{
public:
static double const f ;
} ;
et dans un cpp :
double C::f = 3.14159 ;
excepté dans le corps du constructeur de la classe qui peut
tester si la liste est vide... Mais je trouve cette solution
pas très élégante. Je veux l'initialiser avec une liste de
mots.
est-ce que je peux écrire simplement dans le fichier cpp.
vector<std::string> x;
x.push_back("mot1");
x.push_back("mot2");
etc...
C'est une technique utile quand l'initialisation comporte des
choses qu'on ne peut pas faire avec un constructeur existant.
Dans les deux cas, attention quand même à l'ordre de
l'initialisation, qui n'est pas défini entre des unités de
compilation différente. Si tu t'attends à te servir de cet x
dans le constructeur d'un autre objet statique, dans une autre
unité de compilation, tu risques d'avoir des surprises
désagréables. Dans ces cas-là (et même plus généralement, pour
ne pas exclure cette éventualité à l'avenir), c'est habituel de
se rabattre sur le modèle singleton.
Dans ce cas, quand ce bout de code est exécuté ? (je me pose
cette question parce que ça marche avec mon compilateur, mais
que ça me paraît dangeureux !)
Tel que tu l'as écrit, ça ne doit pas marcher. Tu ne peux mettre
des instructions « exécutables » que dans une fonction. Sauf
qu'évidemment, l'initialisation d'une variable statique peut
comporter des instructions exécutable, par exemple, un
constructeur, ou une expression d'initialisation qui n'est pas
constante. Pour ces instructions-là, la règle veut qu'à
l'intérieur d'une unité de compilation, l'ordre d'initialisation
suit l'ordre des declarations, et que (dans la pratique, au
moins, et dans l'absence d'une édition de liens dynamique)
toutes les initialisations aient lieu avant d'entrer dans
main().
--
James Kanze GABI Software
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
j'ai une classe avec une présentation classique : - déclarations dans le fichier hpp - définitions dans le fichier cpp
je me pose la question de la différence entre une variable globale définie comme suit : dans cpp : vector<std::string> x;
C'est une définition de la variable (avec initialisation par le constructeur par défaut).
et la même chose en tant que membre static private d'une classe (c'est juste une variable utilisée fréquemment dans certaines méthodes (je programme un interpréteur))
C'est à peu près pareil. Quand il s'agit des membres statiques, ce qu'il y a dans la classe, c'est une declaration, non une définition. Il faut donc une définition quelque part ailleurs (dans un cpp).
Dans les deux cas, je ne sais pas comment l'initialiser,
Comme avec n'importe quelle définition.
Donc :
class C { public: static double const f ; } ;
et dans un cpp :
double C::f = 3.14159 ;
excepté dans le corps du constructeur de la classe qui peut tester si la liste est vide... Mais je trouve cette solution pas très élégante. Je veux l'initialiser avec une liste de mots.
est-ce que je peux écrire simplement dans le fichier cpp. vector<std::string> x; x.push_back("mot1"); x.push_back("mot2"); etc...
C'est une technique utile quand l'initialisation comporte des choses qu'on ne peut pas faire avec un constructeur existant.
Dans les deux cas, attention quand même à l'ordre de l'initialisation, qui n'est pas défini entre des unités de compilation différente. Si tu t'attends à te servir de cet x dans le constructeur d'un autre objet statique, dans une autre unité de compilation, tu risques d'avoir des surprises désagréables. Dans ces cas-là (et même plus généralement, pour ne pas exclure cette éventualité à l'avenir), c'est habituel de se rabattre sur le modèle singleton.
Dans ce cas, quand ce bout de code est exécuté ? (je me pose cette question parce que ça marche avec mon compilateur, mais que ça me paraît dangeureux !)
Tel que tu l'as écrit, ça ne doit pas marcher. Tu ne peux mettre des instructions « exécutables » que dans une fonction. Sauf qu'évidemment, l'initialisation d'une variable statique peut comporter des instructions exécutable, par exemple, un constructeur, ou une expression d'initialisation qui n'est pas constante. Pour ces instructions-là, la règle veut qu'à l'intérieur d'une unité de compilation, l'ordre d'initialisation suit l'ordre des declarations, et que (dans la pratique, au moins, et dans l'absence d'une édition de liens dynamique) toutes les initialisations aient lieu avant d'entrer dans main().
-- James Kanze GABI Software 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
Dominique Vaufreydaz
Bonjour,
Perso, je ferais : - un membre static - un autre membre static boolean qui dit si c'est initialise ou pas (a faux donc dans sa declaration).
dans le h.
class MaClasse: { public: MaClasse();
private: // a voir, ca depend des cas Chose MonTrucAInitialiser; bool MonTrucAInitialiserEstIntitialise; }
Maitnenant, si il faut aussi detruire proprementl'objet, *dans certains cas*, il peut etre utilise de rempalcer le booleen par un compteur d'instance. Quand il est a 1, on initialise quand il est a 0, on detruit. Ensuite, si on veux initialiser automatiquement *avant* le main et etre sur que se soit detruit *après* le main, il suffit de rajouter une instance de la classe en global.
Bien penser au mutex pour proteger l'acces au booleen et au compteur d'instances, (ca n'est pas dans mon exemple).
En esperant avoir ete clair. Doms.
Bonjour,
Perso, je ferais :
- un membre static
- un autre membre static boolean qui dit si c'est initialise
ou pas (a faux donc dans sa declaration).
dans le h.
class MaClasse:
{
public:
MaClasse();
private: // a voir, ca depend des cas
Chose MonTrucAInitialiser;
bool MonTrucAInitialiserEstIntitialise;
}
Maitnenant, si il faut aussi detruire proprementl'objet, *dans
certains cas*, il peut etre utilise de rempalcer le booleen par
un compteur d'instance. Quand il est a 1, on initialise quand
il est a 0, on detruit. Ensuite, si on veux initialiser automatiquement
*avant* le main et etre sur que se soit detruit *après* le main,
il suffit de rajouter une instance de la classe en global.
Bien penser au mutex pour proteger l'acces au booleen et
au compteur d'instances, (ca n'est pas dans mon exemple).
Maitnenant, si il faut aussi detruire proprementl'objet, *dans certains cas*, il peut etre utilise de rempalcer le booleen par un compteur d'instance. Quand il est a 1, on initialise quand il est a 0, on detruit. Ensuite, si on veux initialiser automatiquement *avant* le main et etre sur que se soit detruit *après* le main, il suffit de rajouter une instance de la classe en global.
Bien penser au mutex pour proteger l'acces au booleen et au compteur d'instances, (ca n'est pas dans mon exemple).
En esperant avoir ete clair. Doms.
Michel Decima
Pareil, évidemment, si l'objet est un membre statique (sauf qu'il se nomme alors C::x, et non simplement x).
Il y a une raison particuliere qui justifie l'operateur , dans l'initialisation de dummy, plutot qu'un initX() qui retourne un bool ?
MGN
Merci pour vos réponses Je m'aperçois que c'est un peu pareil si je fais if (!theX.empty()) { theX.push_back("mot1"); theX.push_back("mot2"); } dans l'appel du constructeur de mes objets mais alors j'ai un test if à chaque fois... J'avoue que je ne connaissais pas la syntaxe pour initialiser un vecteur à partir d'un tableau. J'ai pourtant plusieurs livres qui parlent de la stl mais ils sont tous très indigestes :-) Marc
Merci pour vos réponses
Je m'aperçois que c'est un peu pareil si je fais
if (!theX.empty())
{
theX.push_back("mot1");
theX.push_back("mot2");
}
dans l'appel du constructeur de mes objets mais alors j'ai un test if à
chaque fois...
J'avoue que je ne connaissais pas la syntaxe pour initialiser un vecteur à
partir d'un tableau.
J'ai pourtant plusieurs livres qui parlent de la stl mais ils sont tous très
indigestes :-)
Marc
Merci pour vos réponses Je m'aperçois que c'est un peu pareil si je fais if (!theX.empty()) { theX.push_back("mot1"); theX.push_back("mot2"); } dans l'appel du constructeur de mes objets mais alors j'ai un test if à chaque fois... J'avoue que je ne connaissais pas la syntaxe pour initialiser un vecteur à partir d'un tableau. J'ai pourtant plusieurs livres qui parlent de la stl mais ils sont tous très indigestes :-) Marc
MGN
oui, c'est clair... je vais faire un truc dans le genre. Pour le cas qui me tracasse, c'est largement suffisant... Marc
oui, c'est clair...
je vais faire un truc dans le genre. Pour le cas qui me tracasse, c'est
largement suffisant...
Marc
Tu n'as pas oublié static devant std::vector< std::string > x ; ? Ou tu utilises une variable globale. Désolé, je comprends pas tout... En tout cas, merci pour ton effort à me répondre ! Marc
Tu n'as pas oublié static devant
std::vector< std::string > x ;
?
Ou tu utilises une variable globale.
Désolé, je comprends pas tout...
En tout cas, merci pour ton effort à me répondre !
Marc
Tu n'as pas oublié static devant std::vector< std::string > x ; ? Ou tu utilises une variable globale. Désolé, je comprends pas tout... En tout cas, merci pour ton effort à me répondre ! Marc