decidement, j ai quelques problemes a bien comprendre les constantes en cpp
voila ce que je fais grosso modo :
class Ligne
public:
static const OK=0;
void toto();
etc
vector<Ligne> toto;
Ligne ligne;
toto.push_back(ligne);
bon
si je fais :
ligne.toto() => ca marche
cout << ligne.OK => ca marche
si je fais :
vector<Ligne>::iterator ptr;
ptr->toto() => ca marche
ptr->OK => ca ne compile pas, erreur au linkage : undefined
reference !!!
la, je ne comprend pas !
quand je passe par ligne, tout fonctionne
quand je passe par l iterateur, l appel aux fonctions marche mais pas l
acces a la constante qui est bien statique pourtant !!!
je vais essayer de donner plus de renseignement, tout en simplifiant le code :
dans ligne.h : class Ligne { string _variable; public: static const int OK = 0; string getNom() { return _variable; }; };
dans fichier.cpp : #include "ligne.h"
As tu pensé à définir ta constante dans le .cpp ?
int const Ligne::OK;
-- Loïc
James Kanze
ricky writes:
|> decidement, j ai quelques problemes a bien comprendre les constantes |> en cpp
|> voila ce que je fais grosso modo :
|> class Ligne |> public: |> static const OK=0; |> void toto(); |> etc
|> vector<Ligne> toto; |> Ligne ligne;
|> toto.push_back(ligne);
|> bon |> si je fais : |> ligne.toto() => ca marche |> cout << ligne.OK => ca marche
|> si je fais : |> vector<Ligne>::iterator ptr;
|> ptr->toto() => ca marche |> ptr->OK => ca ne compile pas, erreur au linkage : undefined |> reference !!!
|> la, je ne comprend pas ! |> quand je passe par ligne, tout fonctionne |> quand je passe par l iterateur, l appel aux fonctions marche mais pas |> l acces a la constante qui est bien statique pourtant !!!
|> j ai encore loupe quoi ce coup ci ?
Plus ou moins, mais le point est subtile.
En gros, la ligne :
static int const OK = 0 ;
dans ta définition de la classe est une declaration, non une définition. Elle dit qu'il y aura une variable Ligne::OK. Elle n'alloue pas la variable. Il te faut aussi, dans une seule module, une définition :
int const Ligne::OK ;
pour dire au compilateur d'allouer la variable.
Allouée ou non, le compilateur connaît la valeur de la variable. Il est donc possible que quand j'écris : ligne.OK, il se sert directement de cette valeur, sans passer par la variable, et qu'il ne génère pas d'entrée dans le fichier d'objet qui exige l'existence de cette variable. Possible, mais pas du tout exigé ; moi, j'ai l'erreur à l'édition de liens déjà avec ligne.OK.
Maintenant, j'avoue ne pas comprendre pourquoi le compilateur fait différemment dans le cas d'un itérateur. À la fin, même s'il doit évaluer l'expression ptr-> (et appeler donc std::vector<Ligne>::iterator::operator->), il doit en ignorer le resultat, et se servir simplement de son type ; par la suite, je ne vois pas où il y aurait une différence. Mais bizarre ou non, il est dans ses droits -- si tu ne fournis pas la définition (ou si tu la fournis plus d'une fois), c'est un comportement indéfini.
-- James Kanze mailto: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
ricky <eric_nyme@yahoo.fr> writes:
|> decidement, j ai quelques problemes a bien comprendre les constantes
|> en cpp
|> voila ce que je fais grosso modo :
|> class Ligne
|> public:
|> static const OK=0;
|> void toto();
|> etc
|> vector<Ligne> toto;
|> Ligne ligne;
|> toto.push_back(ligne);
|> bon
|> si je fais :
|> ligne.toto() => ca marche
|> cout << ligne.OK => ca marche
|> si je fais :
|> vector<Ligne>::iterator ptr;
|> ptr->toto() => ca marche
|> ptr->OK => ca ne compile pas, erreur au linkage : undefined
|> reference !!!
|> la, je ne comprend pas !
|> quand je passe par ligne, tout fonctionne
|> quand je passe par l iterateur, l appel aux fonctions marche mais pas
|> l acces a la constante qui est bien statique pourtant !!!
|> j ai encore loupe quoi ce coup ci ?
Plus ou moins, mais le point est subtile.
En gros, la ligne :
static int const OK = 0 ;
dans ta définition de la classe est une declaration, non une
définition. Elle dit qu'il y aura une variable Ligne::OK. Elle
n'alloue pas la variable. Il te faut aussi, dans une seule module, une
définition :
int const Ligne::OK ;
pour dire au compilateur d'allouer la variable.
Allouée ou non, le compilateur connaît la valeur de la variable.
Il est donc possible que quand j'écris : ligne.OK, il se sert
directement de cette valeur, sans passer par la variable, et qu'il ne
génère pas d'entrée dans le fichier d'objet qui exige
l'existence de cette variable. Possible, mais pas du tout exigé ;
moi, j'ai l'erreur à l'édition de liens déjà avec ligne.OK.
Maintenant, j'avoue ne pas comprendre pourquoi le compilateur fait
différemment dans le cas d'un itérateur. À la fin, même s'il
doit évaluer l'expression ptr-> (et appeler donc
std::vector<Ligne>::iterator::operator->), il doit en ignorer le
resultat, et se servir simplement de son type ; par la suite, je ne vois
pas où il y aurait une différence. Mais bizarre ou non, il est
dans ses droits -- si tu ne fournis pas la définition (ou si tu la
fournis plus d'une fois), c'est un comportement indéfini.
--
James Kanze mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
|> decidement, j ai quelques problemes a bien comprendre les constantes |> en cpp
|> voila ce que je fais grosso modo :
|> class Ligne |> public: |> static const OK=0; |> void toto(); |> etc
|> vector<Ligne> toto; |> Ligne ligne;
|> toto.push_back(ligne);
|> bon |> si je fais : |> ligne.toto() => ca marche |> cout << ligne.OK => ca marche
|> si je fais : |> vector<Ligne>::iterator ptr;
|> ptr->toto() => ca marche |> ptr->OK => ca ne compile pas, erreur au linkage : undefined |> reference !!!
|> la, je ne comprend pas ! |> quand je passe par ligne, tout fonctionne |> quand je passe par l iterateur, l appel aux fonctions marche mais pas |> l acces a la constante qui est bien statique pourtant !!!
|> j ai encore loupe quoi ce coup ci ?
Plus ou moins, mais le point est subtile.
En gros, la ligne :
static int const OK = 0 ;
dans ta définition de la classe est une declaration, non une définition. Elle dit qu'il y aura une variable Ligne::OK. Elle n'alloue pas la variable. Il te faut aussi, dans une seule module, une définition :
int const Ligne::OK ;
pour dire au compilateur d'allouer la variable.
Allouée ou non, le compilateur connaît la valeur de la variable. Il est donc possible que quand j'écris : ligne.OK, il se sert directement de cette valeur, sans passer par la variable, et qu'il ne génère pas d'entrée dans le fichier d'objet qui exige l'existence de cette variable. Possible, mais pas du tout exigé ; moi, j'ai l'erreur à l'édition de liens déjà avec ligne.OK.
Maintenant, j'avoue ne pas comprendre pourquoi le compilateur fait différemment dans le cas d'un itérateur. À la fin, même s'il doit évaluer l'expression ptr-> (et appeler donc std::vector<Ligne>::iterator::operator->), il doit en ignorer le resultat, et se servir simplement de son type ; par la suite, je ne vois pas où il y aurait une différence. Mais bizarre ou non, il est dans ses droits -- si tu ne fournis pas la définition (ou si tu la fournis plus d'une fois), c'est un comportement indéfini.
-- James Kanze mailto: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
ricky
bonjour
As tu pensé à définir ta constante dans le .cpp ?
int const Ligne::OK;
merci a vous deux (avec james)!
effectivement, je n'avais pas vu l'interet de cette ligne, d'autant que cela marchait bien quand je passait directement par l'objet...
cette subtilite m'avait completement echappe, mais j'ai compris la lecon :-)
cordialement ricky
bonjour
As tu pensé à définir ta constante dans le .cpp ?
int const Ligne::OK;
merci a vous deux (avec james)!
effectivement, je n'avais pas vu l'interet de cette ligne, d'autant que
cela marchait bien quand je passait directement par l'objet...
cette subtilite m'avait completement echappe, mais j'ai compris la lecon
:-)
effectivement, je n'avais pas vu l'interet de cette ligne, d'autant que cela marchait bien quand je passait directement par l'objet...
cette subtilite m'avait completement echappe, mais j'ai compris la lecon :-)
cordialement ricky
ricky
bonjour
Plus ou moins, mais le point est subtile.
En gros, la ligne :
static int const OK = 0 ;
dans ta définition de la classe est une declaration, non une définition.
oui en effet !
Elle dit qu'il y aura une variable Ligne::OK. Elle n'alloue pas la variable.
je pensait que la declaration avec le " = 0 " permettait au compilateur de se debrouiller avec une constante (statique qui plus est) ...
Il te faut aussi, dans une seule module, une
définition :
int const Ligne::OK ;
pour dire au compilateur d'allouer la variable.
oui cela a marche en effet ... logique avec ton explication !
Allouée ou non, le compilateur connaît la valeur de la variable.
oui, c est pour cela que je pensais que cela suffisait pour une constante !!! on a sa declaration, et la valeur qu'elle sera censee avoir une fois pour toute !
Il est donc possible que quand j'écris : ligne.OK, il se sert directement de cette valeur, sans passer par la variable, et qu'il ne génère pas d'entrée dans le fichier d'objet qui exige l'existence de cette variable. Possible, mais pas du tout exigé ;
oui j'ai constate !
moi, j'ai l'erreur à l'édition de liens déjà avec ligne.OK.
j'aurais prefere, je me serais pose moins de question.. surtout que, honte a moi, pour les constantes, j'ai toujours fait comme cela !
std::vector<Ligne>::iterator::operator->), il doit en ignorer le resultat, et se servir simplement de son type ; par la suite, je ne vois pas où il y aurait une différence.
peut etre que "ignorer le resultat" n'empeche pas quand meme de lever une erreur au moment ou il le genere, meme s'il ne l'utilise pas...
Mais bizarre ou non, il est dans ses droits --
pffff ces compilos :-) et l'esprit du droit alors :-) apres tout, pour une constante, donner son nom et sa valeur, cela devrait suffir !
si tu ne fournis pas la définition (ou si tu la fournis plus d'une fois), c'est un comportement indéfini.
bien compris
merci pour toutes ces explications
cordialement ricky
bonjour
Plus ou moins, mais le point est subtile.
En gros, la ligne :
static int const OK = 0 ;
dans ta définition de la classe est une declaration, non une
définition.
oui en effet !
Elle dit qu'il y aura une variable Ligne::OK. Elle
n'alloue pas la variable.
je pensait que la declaration avec le " = 0 " permettait au compilateur
de se debrouiller avec une constante (statique qui plus est) ...
Il te faut aussi, dans une seule module, une
définition :
int const Ligne::OK ;
pour dire au compilateur d'allouer la variable.
oui cela a marche en effet ... logique avec ton explication !
Allouée ou non, le compilateur connaît la valeur de la variable.
oui, c est pour cela que je pensais que cela suffisait pour une
constante !!! on a sa declaration, et la valeur qu'elle sera censee
avoir une fois pour toute !
Il est donc possible que quand j'écris : ligne.OK, il se sert
directement de cette valeur, sans passer par la variable, et qu'il ne
génère pas d'entrée dans le fichier d'objet qui exige
l'existence de cette variable. Possible, mais pas du tout exigé ;
oui j'ai constate !
moi, j'ai l'erreur à l'édition de liens déjà avec ligne.OK.
j'aurais prefere, je me serais pose moins de question.. surtout que,
honte a moi, pour les constantes, j'ai toujours fait comme cela !
std::vector<Ligne>::iterator::operator->), il doit en ignorer le
resultat, et se servir simplement de son type ; par la suite, je ne vois
pas où il y aurait une différence.
peut etre que "ignorer le resultat" n'empeche pas quand meme de lever
une erreur au moment ou il le genere, meme s'il ne l'utilise pas...
Mais bizarre ou non, il est
dans ses droits --
pffff ces compilos :-) et l'esprit du droit alors :-)
apres tout, pour une constante, donner son nom et sa valeur, cela
devrait suffir !
si tu ne fournis pas la définition (ou si tu la
fournis plus d'une fois), c'est un comportement indéfini.
dans ta définition de la classe est une declaration, non une définition.
oui en effet !
Elle dit qu'il y aura une variable Ligne::OK. Elle n'alloue pas la variable.
je pensait que la declaration avec le " = 0 " permettait au compilateur de se debrouiller avec une constante (statique qui plus est) ...
Il te faut aussi, dans une seule module, une
définition :
int const Ligne::OK ;
pour dire au compilateur d'allouer la variable.
oui cela a marche en effet ... logique avec ton explication !
Allouée ou non, le compilateur connaît la valeur de la variable.
oui, c est pour cela que je pensais que cela suffisait pour une constante !!! on a sa declaration, et la valeur qu'elle sera censee avoir une fois pour toute !
Il est donc possible que quand j'écris : ligne.OK, il se sert directement de cette valeur, sans passer par la variable, et qu'il ne génère pas d'entrée dans le fichier d'objet qui exige l'existence de cette variable. Possible, mais pas du tout exigé ;
oui j'ai constate !
moi, j'ai l'erreur à l'édition de liens déjà avec ligne.OK.
j'aurais prefere, je me serais pose moins de question.. surtout que, honte a moi, pour les constantes, j'ai toujours fait comme cela !
std::vector<Ligne>::iterator::operator->), il doit en ignorer le resultat, et se servir simplement de son type ; par la suite, je ne vois pas où il y aurait une différence.
peut etre que "ignorer le resultat" n'empeche pas quand meme de lever une erreur au moment ou il le genere, meme s'il ne l'utilise pas...
Mais bizarre ou non, il est dans ses droits --
pffff ces compilos :-) et l'esprit du droit alors :-) apres tout, pour une constante, donner son nom et sa valeur, cela devrait suffir !
si tu ne fournis pas la définition (ou si tu la fournis plus d'une fois), c'est un comportement indéfini.
bien compris
merci pour toutes ces explications
cordialement ricky
dpr
bonjour
decidement, j ai quelques problemes a bien comprendre les constantes en cpp
voila ce que je fais grosso modo :
class Ligne public: static const OK=0; void toto(); etc
vector<Ligne> toto; Ligne ligne;
toto.push_back(ligne);
bon si je fais : ligne.toto() => ca marche cout << ligne.OK => ca marche
si je fais : vector<Ligne>::iterator ptr;
ptr->toto() => ca marche ptr->OK => ca ne compile pas, erreur au linkage : undefined reference !!!
la, je ne comprend pas ! quand je passe par ligne, tout fonctionne quand je passe par l iterateur, l appel aux fonctions marche mais pas l acces a la constante qui est bien statique pourtant !!!
j ai encore loupe quoi ce coup ci ?
@+ ricky
Il n'y a qu'une seule valeur pour OK (car statique) pour toute les
instances de la classe Ligne. C'est pkoi c mieux et plus logique d'utiliser "Ligne::OK" plutot que "uneLigne.OK".
bonjour
decidement, j ai quelques problemes a bien comprendre les constantes en cpp
voila ce que je fais grosso modo :
class Ligne
public:
static const OK=0;
void toto();
etc
vector<Ligne> toto;
Ligne ligne;
toto.push_back(ligne);
bon
si je fais :
ligne.toto() => ca marche
cout << ligne.OK => ca marche
si je fais :
vector<Ligne>::iterator ptr;
ptr->toto() => ca marche
ptr->OK => ca ne compile pas, erreur au linkage : undefined
reference !!!
la, je ne comprend pas !
quand je passe par ligne, tout fonctionne
quand je passe par l iterateur, l appel aux fonctions marche mais pas l
acces a la constante qui est bien statique pourtant !!!
j ai encore loupe quoi ce coup ci ?
@+
ricky
Il n'y a qu'une seule valeur pour OK (car statique) pour toute les
instances de la classe Ligne. C'est pkoi c mieux et plus logique
d'utiliser "Ligne::OK" plutot que "uneLigne.OK".
decidement, j ai quelques problemes a bien comprendre les constantes en cpp
voila ce que je fais grosso modo :
class Ligne public: static const OK=0; void toto(); etc
vector<Ligne> toto; Ligne ligne;
toto.push_back(ligne);
bon si je fais : ligne.toto() => ca marche cout << ligne.OK => ca marche
si je fais : vector<Ligne>::iterator ptr;
ptr->toto() => ca marche ptr->OK => ca ne compile pas, erreur au linkage : undefined reference !!!
la, je ne comprend pas ! quand je passe par ligne, tout fonctionne quand je passe par l iterateur, l appel aux fonctions marche mais pas l acces a la constante qui est bien statique pourtant !!!
j ai encore loupe quoi ce coup ci ?
@+ ricky
Il n'y a qu'une seule valeur pour OK (car statique) pour toute les
instances de la classe Ligne. C'est pkoi c mieux et plus logique d'utiliser "Ligne::OK" plutot que "uneLigne.OK".