peut-on définir une fonction membre statique dans un fichier .cpp ?
35 réponses
Aurélien Barbier-Accary
Bonjour,
petite question comme ça, tout est dans le titre.
Puisqu'on peut écrire
// dans le .hpp
classe cA
{
public:
static const double val;
static const double fonc(const double& d) { return 2*d; }
//...
};
// dans le .cpp
const double cA::val = 1.0;
Comment écrire ceci :
// dans le .hpp
classe cB
{
public:
static const double val;
static const double fonc(const double& d);
//...
};
// dans le .cpp
const double cB::val = 1.0;
const double cB::fonc(const double& d) { return 2*d; }
Chez moi (gcc), ça m'indique des erreurs dans la fonction qui suit le prototype
de la fonction membre statique.
J'ai essayé de ne pas définir une fonction mais un pointeur de fonction mais
j'ai la même erreur.
On Sat, 15 Oct 2005 09:25:49 +0200, Franck Branjonneau :
Même dans le cas des constructeurs (dont la liste d'initialisation est non vide) ?
C'est effectivement le seul cas où ça pourrait être utile.
Note toutefois que si le constructeur d'un membre (ou d'une classe de base) renvoie une exception, l'objet ne peut pas être créé, donc doit lui-même renvoyer une exception. Les possibilités pour le "catch" seront alors assez limitées : enregistrement éventuel de l'erreur dans un fichier log, puis renvoi de l'exception (ou d'une autre exception).
On Sat, 15 Oct 2005 09:25:49 +0200, Franck Branjonneau
<fasbjx@free.fr>:
Même dans le cas des constructeurs (dont la liste d'initialisation est
non vide) ?
C'est effectivement le seul cas où ça pourrait être utile.
Note toutefois que si le constructeur d'un membre (ou d'une classe de
base) renvoie une exception, l'objet ne peut pas être créé, donc doit
lui-même renvoyer une exception. Les possibilités pour le "catch"
seront alors assez limitées : enregistrement éventuel de l'erreur dans
un fichier log, puis renvoi de l'exception (ou d'une autre exception).
On Sat, 15 Oct 2005 09:25:49 +0200, Franck Branjonneau :
Même dans le cas des constructeurs (dont la liste d'initialisation est non vide) ?
C'est effectivement le seul cas où ça pourrait être utile.
Note toutefois que si le constructeur d'un membre (ou d'une classe de base) renvoie une exception, l'objet ne peut pas être créé, donc doit lui-même renvoyer une exception. Les possibilités pour le "catch" seront alors assez limitées : enregistrement éventuel de l'erreur dans un fichier log, puis renvoi de l'exception (ou d'une autre exception).
Aurélien Barbier-Accary
On Sat, 15 Oct 2005 05:11:41 +0200, Aurélien Barbier-Accary :
static const Truc val; static const Truc fonc() { return Truc(-1.0, 0.0); } // ces valeurs n'ont pas à être modifiées, elles jouent un rôle de constantes
Gnii ?..
Le "static const Truc val;" est correct, il n'y a rien à dire.
Le const de "static const Truc fonc()" est au contraire inutile : même si tu ne spécifies pas "const", l'objet retourné est de toutes façons est une rvalue :
class C { public: static int fonc() { return 5; } };
int main() { C::fonc()= 3; // Erreur ici car C::fonc() est une rvalue. }
Non, ce n'est pas inutile, la preuve est donnée par l'exemple suivant qui est possible à tort si on ne met pas le const qui fait débat :
const Truc cB::val = Truc(1.0, 0.0); Pourquoi une écriture si compliquée ?
const Truc cB::val (1.0, 0.0); est plus simple, et évite une copie inutile.
alors là c'est une habitude de travail prise à force d'insistance d'un de mes chefs, mais apparemment à la contruction les deux instructions seraient équivalentes car détectées par le compilateur !? Mais tu as raison, il faudrait que je reprenne de bonnes habitudes.
Pour le reste nous y avons tout deux déjà répondu dans un autre fil.
On Sat, 15 Oct 2005 05:11:41 +0200, Aurélien Barbier-Accary
<nospam_star-shoot_mapson@fr.st>:
static const Truc val;
static const Truc fonc() { return Truc(-1.0, 0.0); }
// ces valeurs n'ont pas à être modifiées, elles jouent un rôle de constantes
Gnii ?..
Le "static const Truc val;" est correct, il n'y a rien à dire.
Le const de "static const Truc fonc()" est au contraire inutile : même
si tu ne spécifies pas "const", l'objet retourné est de toutes façons
est une rvalue :
class C
{
public:
static int fonc() { return 5; }
};
int main()
{
C::fonc()= 3; // Erreur ici car C::fonc() est une rvalue.
}
Non, ce n'est pas inutile, la preuve est donnée par l'exemple suivant qui est
possible à tort si on ne met pas le const qui fait débat :
const Truc cB::val = Truc(1.0, 0.0);
Pourquoi une écriture si compliquée ?
const Truc cB::val (1.0, 0.0);
est plus simple, et évite une copie inutile.
alors là c'est une habitude de travail prise à force d'insistance d'un de mes
chefs, mais apparemment à la contruction les deux instructions seraient
équivalentes car détectées par le compilateur !?
Mais tu as raison, il faudrait que je reprenne de bonnes habitudes.
Pour le reste nous y avons tout deux déjà répondu dans un autre fil.
On Sat, 15 Oct 2005 05:11:41 +0200, Aurélien Barbier-Accary :
static const Truc val; static const Truc fonc() { return Truc(-1.0, 0.0); } // ces valeurs n'ont pas à être modifiées, elles jouent un rôle de constantes
Gnii ?..
Le "static const Truc val;" est correct, il n'y a rien à dire.
Le const de "static const Truc fonc()" est au contraire inutile : même si tu ne spécifies pas "const", l'objet retourné est de toutes façons est une rvalue :
class C { public: static int fonc() { return 5; } };
int main() { C::fonc()= 3; // Erreur ici car C::fonc() est une rvalue. }
Non, ce n'est pas inutile, la preuve est donnée par l'exemple suivant qui est possible à tort si on ne met pas le const qui fait débat :
const Truc cB::val = Truc(1.0, 0.0); Pourquoi une écriture si compliquée ?
const Truc cB::val (1.0, 0.0); est plus simple, et évite une copie inutile.
alors là c'est une habitude de travail prise à force d'insistance d'un de mes chefs, mais apparemment à la contruction les deux instructions seraient équivalentes car détectées par le compilateur !? Mais tu as raison, il faudrait que je reprenne de bonnes habitudes.
Pour le reste nous y avons tout deux déjà répondu dans un autre fil.
Aurélien Barbier-Accary
Aurélien Barbier-Accary écrivait:
Chez moi (gcc), ça m'indique des erreurs dans la fonction qui suit le prototype de la fonction membre statique.
Ton code me semble correct (modulo s/classe/class/). Puisque l'erreur apparaît après le prototype et uniquement dans le cpp, je chercherais si je n'inclus pas dans ce cpp un fichier qui définit une macro fonc.
Bien vu mais en fait c'était encore plus bête (étrange) que ça. cf le fil intitulé: [Boulet] pas un pb de fonction statique mais de function try block :-( Désolé mais je ne sais pas faire de lien vers des messages de news.
Chez moi (gcc), ça m'indique des erreurs dans la fonction qui suit
le prototype de la fonction membre statique.
Ton code me semble correct (modulo s/classe/class/). Puisque l'erreur
apparaît après le prototype et uniquement dans le cpp, je chercherais
si je n'inclus pas dans ce cpp un fichier qui définit une macro fonc.
Bien vu mais en fait c'était encore plus bête (étrange) que ça.
cf le fil intitulé:
[Boulet] pas un pb de fonction statique mais de function try block :-(
Désolé mais je ne sais pas faire de lien vers des messages de news.
Chez moi (gcc), ça m'indique des erreurs dans la fonction qui suit le prototype de la fonction membre statique.
Ton code me semble correct (modulo s/classe/class/). Puisque l'erreur apparaît après le prototype et uniquement dans le cpp, je chercherais si je n'inclus pas dans ce cpp un fichier qui définit une macro fonc.
Bien vu mais en fait c'était encore plus bête (étrange) que ça. cf le fil intitulé: [Boulet] pas un pb de fonction statique mais de function try block :-( Désolé mais je ne sais pas faire de lien vers des messages de news.
Merci pour ta réponse !!
Fabien LE LEZ
On Sat, 15 Oct 2005 10:38:15 +0200, Aurélien Barbier-Accary :
Désolé mais je ne sais pas faire de lien vers des messages de news.
C'est fort simple : il suffit de prendre le message-id et d'écrire "news:" devant. Par exemple, ton message de 10h38 (auquel je réponds) a le header suivant : Message-ID: <4350bff8$0$21232$
Le lien est donc :
<news:4350bff8$0$21232$
On Sat, 15 Oct 2005 10:38:15 +0200, Aurélien Barbier-Accary
<nospam_star-shoot_mapson@fr.st>:
Désolé mais je ne sais pas faire de lien vers des messages de news.
C'est fort simple : il suffit de prendre le message-id et d'écrire
"news:" devant.
Par exemple, ton message de 10h38 (auquel je réponds) a le header
suivant :
Message-ID: <4350bff8$0$21232$626a54ce@news.free.fr>
On Sat, 15 Oct 2005 10:38:15 +0200, Aurélien Barbier-Accary :
Désolé mais je ne sais pas faire de lien vers des messages de news.
C'est fort simple : il suffit de prendre le message-id et d'écrire "news:" devant. Par exemple, ton message de 10h38 (auquel je réponds) a le header suivant : Message-ID: <4350bff8$0$21232$
Le lien est donc :
<news:4350bff8$0$21232$
Fabien LE LEZ
On Sat, 15 Oct 2005 10:35:02 +0200, Aurélien Barbier-Accary :
[...]
Le code suivant est correct :
class C { public: static Truc fonc() { return Truc(2,3); } };
int main() { std::cout << (C::fonc()= Truc(1,0)); }
On peut se poser des questions sur le programmeur qui a écrit ça, mais bon... En quoi est-ce gênant que l'affectation soit possible ?
On Sat, 15 Oct 2005 10:35:02 +0200, Aurélien Barbier-Accary
<nospam_star-shoot_mapson@fr.st>:
[...]
Le code suivant est correct :
class C
{
public:
static Truc fonc() { return Truc(2,3); }
};
int main()
{
std::cout << (C::fonc()= Truc(1,0));
}
On peut se poser des questions sur le programmeur qui a écrit ça, mais
bon...
En quoi est-ce gênant que l'affectation soit possible ?
On Sat, 15 Oct 2005 10:35:02 +0200, Aurélien Barbier-Accary :
[...]
Le code suivant est correct :
class C { public: static Truc fonc() { return Truc(2,3); } };
int main() { std::cout << (C::fonc()= Truc(1,0)); }
On peut se poser des questions sur le programmeur qui a écrit ça, mais bon...
Original ;-)
En quoi est-ce gênant que l'affectation soit possible ?
Si mes souvenirs sont bons c'est discuté dans un des premiers GotW. Eviter des choses commme a+b=c;. -- Franck Branjonneau
Franck Branjonneau
Fabien LE LEZ écrivait:
On Sat, 15 Oct 2005 09:25:49 +0200, Franck Branjonneau :
Même dans le cas des constructeurs (dont la liste d'initialisation est non vide) ?
C'est effectivement le seul cas où ça pourrait être utile.
Note toutefois que si le constructeur d'un membre (ou d'une classe de base) renvoie une exception, l'objet ne peut pas être créé, donc doit lui-même renvoyer une exception. Les possibilités pour le "catch" seront alors assez limitées : enregistrement éventuel de l'erreur dans un fichier log, puis renvoi de l'exception (ou d'une autre exception).
struct S {
static int const default= 0; int * p1, p2, p3, p4;
On Sat, 15 Oct 2005 09:25:49 +0200, Franck Branjonneau
<fasbjx@free.fr>:
Même dans le cas des constructeurs (dont la liste d'initialisation est
non vide) ?
C'est effectivement le seul cas où ça pourrait être utile.
Note toutefois que si le constructeur d'un membre (ou d'une classe de
base) renvoie une exception, l'objet ne peut pas être créé, donc doit
lui-même renvoyer une exception. Les possibilités pour le "catch"
seront alors assez limitées : enregistrement éventuel de l'erreur dans
un fichier log, puis renvoi de l'exception (ou d'une autre exception).
struct S {
static int const default= 0;
int * p1, p2, p3, p4;
On Sat, 15 Oct 2005 09:25:49 +0200, Franck Branjonneau :
Même dans le cas des constructeurs (dont la liste d'initialisation est non vide) ?
C'est effectivement le seul cas où ça pourrait être utile.
Note toutefois que si le constructeur d'un membre (ou d'une classe de base) renvoie une exception, l'objet ne peut pas être créé, donc doit lui-même renvoyer une exception. Les possibilités pour le "catch" seront alors assez limitées : enregistrement éventuel de l'erreur dans un fichier log, puis renvoi de l'exception (ou d'une autre exception).
struct S {
static int const default= 0; int * p1, p2, p3, p4;
On Sat, 15 Oct 2005 10:38:15 +0200, Aurélien Barbier-Accary :
Désolé mais je ne sais pas faire de lien vers des messages de news.
C'est fort simple : il suffit de prendre le message-id et d'écrire "news:" devant. Par exemple, ton message de 10h38 (auquel je réponds) a le header suivant : Message-ID: <4350bff8$0$21232$
Le lien est donc :
<news:4350bff8$0$21232$
ok, merci !
On Sat, 15 Oct 2005 10:38:15 +0200, Aurélien Barbier-Accary
<nospam_star-shoot_mapson@fr.st>:
Désolé mais je ne sais pas faire de lien vers des messages de news.
C'est fort simple : il suffit de prendre le message-id et d'écrire
"news:" devant.
Par exemple, ton message de 10h38 (auquel je réponds) a le header
suivant :
Message-ID: <4350bff8$0$21232$626a54ce@news.free.fr>
On Sat, 15 Oct 2005 10:38:15 +0200, Aurélien Barbier-Accary :
Désolé mais je ne sais pas faire de lien vers des messages de news.
C'est fort simple : il suffit de prendre le message-id et d'écrire "news:" devant. Par exemple, ton message de 10h38 (auquel je réponds) a le header suivant : Message-ID: <4350bff8$0$21232$
Le lien est donc :
<news:4350bff8$0$21232$
ok, merci !
Fabien LE LEZ
On Sat, 15 Oct 2005 14:45:19 +0200, Franck Branjonneau :
int * p1, p2, p3, p4;
Je déconseille fortement la déclaration de plusieurs variables sur la même ligne. D'ailleurs, tu viens apporter de l'eau à mon moulin en déclarant à ton insu un pointeur et trois entiers...
On Sat, 15 Oct 2005 14:45:19 +0200, Franck Branjonneau
<fasbjx@free.fr>:
int * p1, p2, p3, p4;
Je déconseille fortement la déclaration de plusieurs variables sur la
même ligne.
D'ailleurs, tu viens apporter de l'eau à mon moulin en déclarant à ton
insu un pointeur et trois entiers...
On Sat, 15 Oct 2005 14:45:19 +0200, Franck Branjonneau :
int * p1, p2, p3, p4;
Je déconseille fortement la déclaration de plusieurs variables sur la même ligne. D'ailleurs, tu viens apporter de l'eau à mon moulin en déclarant à ton insu un pointeur et trois entiers...