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.
Comment veux-tu trapper une exception levée dans le constructeur d'elemA ou dans fonctionStatique() sinon ?
S'il s'applique aux autres fonctions, je crois que c'est sûrtout par souci de homogénéité, pour éviter que les constructeurs soient un cas spécial.
-- James Kanze mailto: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Fabien LE LEZ wrote:
On Sat, 15 Oct 2005 05:59:23 +0200, Aurélien Barbier-Accary
<nospam_star-shoot_mapson@fr.st>:
Comment veux-tu trapper une exception levée dans le constructeur
d'elemA ou dans fonctionStatique() sinon ?
S'il s'applique aux autres fonctions, je crois que c'est sûrtout
par souci de homogénéité, pour éviter que les constructeurs
soient un cas spécial.
--
James Kanze mailto: james.kanze@free.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Comment veux-tu trapper une exception levée dans le constructeur d'elemA ou dans fonctionStatique() sinon ?
S'il s'applique aux autres fonctions, je crois que c'est sûrtout par souci de homogénéité, pour éviter que les constructeurs soient un cas spécial.
-- James Kanze mailto: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
James Kanze
Fabien LE LEZ wrote:
Une réécriture minimale de cette classe serait :
struct S { static int const default= 0; int *p1, *p2, *p3;
Sauf que je crois qu'on préfèrerais une version avec des pointeurs intelligents.
L'exemple marche bien s'il y a un pointeur et deux int, avec des fonctions initialize1, initialize2 et initialize3, où initialize2 ou initialize3 pourrait lever une exception. J'ai dû mal à imaginer un exemple réaliste, et j'avoue ne jamais en avoir senti le besoin. Mais de là à dire que ça n'a aucune utilité ?
-- James Kanze mailto: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Fabien LE LEZ wrote:
Une réécriture minimale de cette classe serait :
struct S
{
static int const default= 0;
int *p1, *p2, *p3;
Sauf que je crois qu'on préfèrerais une version avec des
pointeurs intelligents.
L'exemple marche bien s'il y a un pointeur et deux int, avec des
fonctions initialize1, initialize2 et initialize3, où
initialize2 ou initialize3 pourrait lever une exception. J'ai dû
mal à imaginer un exemple réaliste, et j'avoue ne jamais en avoir
senti le besoin. Mais de là à dire que ça n'a aucune utilité ?
--
James Kanze mailto: james.kanze@free.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Sauf que je crois qu'on préfèrerais une version avec des pointeurs intelligents.
L'exemple marche bien s'il y a un pointeur et deux int, avec des fonctions initialize1, initialize2 et initialize3, où initialize2 ou initialize3 pourrait lever une exception. J'ai dû mal à imaginer un exemple réaliste, et j'avoue ne jamais en avoir senti le besoin. Mais de là à dire que ça n'a aucune utilité ?
-- James Kanze mailto: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Fabien LE LEZ
On Sun, 16 Oct 2005 00:07:45 +0200, James Kanze :
Sauf que je crois qu'on préfèrerais une version avec des pointeurs intelligents.
Certes. C'est pour ça que j'ai écrit "réécriture minimale". J'entends par là "Remplacer un programme qui ne fonctionne pas, en un programme qui fonctionne, tout en changeant le moins de choses possibles."
On Sun, 16 Oct 2005 00:07:45 +0200, James Kanze <kanze@none>:
Sauf que je crois qu'on préfèrerais une version avec des
pointeurs intelligents.
Certes. C'est pour ça que j'ai écrit "réécriture minimale". J'entends
par là "Remplacer un programme qui ne fonctionne pas, en un programme
qui fonctionne, tout en changeant le moins de choses possibles."
Sauf que je crois qu'on préfèrerais une version avec des pointeurs intelligents.
Certes. C'est pour ça que j'ai écrit "réécriture minimale". J'entends par là "Remplacer un programme qui ne fonctionne pas, en un programme qui fonctionne, tout en changeant le moins de choses possibles."
David Deharbe
Cela permet au compilateur de détecter l'erreur classique où le programmeur utilise operator= au lieu d'operator==.
David. --
Cela permet au compilateur de détecter l'erreur classique où le
programmeur utilise operator= au lieu d'operator==.
Je viens de me rendre compte que ce code est encore plus incorrect que ce que j'imaginais : quand on est dans le bloc "catch", si je ne m'abuse, l'objet de classe S n'a jamais existé. Donc, parler du membre p1 (ou p2 ou p3) n'a aucun sens.
On Sat, 15 Oct 2005 14:45:19 +0200, Franck Branjonneau
<fasbjx@free.fr>:
struct S {
static int const default= 0;
int * p1, p2, p3, p4;
Je viens de me rendre compte que ce code est encore plus incorrect que
ce que j'imaginais : quand on est dans le bloc "catch", si je ne
m'abuse, l'objet de classe S n'a jamais existé. Donc, parler du membre
p1 (ou p2 ou p3) n'a aucun sens.
Je viens de me rendre compte que ce code est encore plus incorrect que ce que j'imaginais : quand on est dans le bloc "catch", si je ne m'abuse, l'objet de classe S n'a jamais existé. Donc, parler du membre p1 (ou p2 ou p3) n'a aucun sens.
Fabien LE LEZ
On Sun, 16 Oct 2005 00:00:55 +0200, James Kanze :
Il a été introduit afin de pouvoir attrapper les exceptions levées dans la partie initialisateur des constructeurs :
T'arrive-t-il d'utiliser ce mécanisme ? Si oui, pourrais-tu me donner un exemple réel ?
Et, accessoirement, que penses-tu de <http://www.gotw.ca/gotw/066.htm> (ou les items 17 et 18 de "More exceptional C++") ?
On Sun, 16 Oct 2005 00:00:55 +0200, James Kanze <kanze@none>:
Il a été introduit afin de pouvoir attrapper les exceptions
levées dans la partie initialisateur des constructeurs :
T'arrive-t-il d'utiliser ce mécanisme ?
Si oui, pourrais-tu me donner un exemple réel ?
Et, accessoirement, que penses-tu de <http://www.gotw.ca/gotw/066.htm>
(ou les items 17 et 18 de "More exceptional C++") ?
Il a été introduit afin de pouvoir attrapper les exceptions levées dans la partie initialisateur des constructeurs :
T'arrive-t-il d'utiliser ce mécanisme ? Si oui, pourrais-tu me donner un exemple réel ?
Et, accessoirement, que penses-tu de <http://www.gotw.ca/gotw/066.htm> (ou les items 17 et 18 de "More exceptional C++") ?
Franck Branjonneau
Fabien LE LEZ écrivait:
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.
Oui.
Si je ne m'abuse, c'est un comportement indéfini
Oui.
Mon code, complètement erroné, voulait illustrer que si
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).
est le comportement le plus général ; il est des cas où ce n'est pas vrai. -- Franck Branjonneau
Fabien LE LEZ <gramster@gramster.com> écrivait:
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.
Oui.
Si je ne m'abuse, c'est un comportement indéfini
Oui.
Mon code, complètement erroné, voulait illustrer que si
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).
est le comportement le plus général ; il est des cas où ce n'est pas
vrai.
--
Franck Branjonneau <fasbjx@free.fr>
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.
Oui.
Si je ne m'abuse, c'est un comportement indéfini
Oui.
Mon code, complètement erroné, voulait illustrer que si
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).
est le comportement le plus général ; il est des cas où ce n'est pas vrai. -- Franck Branjonneau
Franck Branjonneau
Fabien LE LEZ écrivait:
J'entends par là "Remplacer un programme qui ne fonctionne pas, en un programme qui fonctionne, tout en changeant le moins de choses possibles."
Même pas ;-) Il manque s/default/default_/ -- Franck Branjonneau
Fabien LE LEZ <gramster@gramster.com> écrivait:
J'entends par là "Remplacer un programme qui ne fonctionne pas, en
un programme qui fonctionne, tout en changeant le moins de choses
possibles."
Même pas ;-) Il manque s/default/default_/
--
Franck Branjonneau <fasbjx@free.fr>
Je viens de me rendre compte que ce code est encore plus incorrect que ce que j'imaginais : quand on est dans le bloc "catch", si je ne m'abuse, l'objet de classe S n'a jamais existé.
En fait, la norme dit que toute partie correctement construite est détruite à l'entrée du handler.
Donc, parler du membre p1 (ou p2 ou p3) n'a aucun sens.
Oui c'est du comportement indéfini. On ne peut utiliser que les membres statiques de la classe et les paramètres du constructeur.
De plus, dans le cas d'un constructeur ou d'un destructeur, l'exception attrapée est relancée si le flot de contrôle atteint la fin du handler. -- Franck Branjonneau
Fabien LE LEZ <gramster@gramster.com> écrivait:
On Sat, 15 Oct 2005 14:45:19 +0200, Franck Branjonneau
<fasbjx@free.fr>:
struct S {
static int const default= 0;
int * p1, p2, p3, p4;
Je viens de me rendre compte que ce code est encore plus incorrect que
ce que j'imaginais : quand on est dans le bloc "catch", si je ne
m'abuse, l'objet de classe S n'a jamais existé.
En fait, la norme dit que toute partie correctement construite est
détruite à l'entrée du handler.
Donc, parler du membre p1 (ou p2 ou p3) n'a aucun sens.
Oui c'est du comportement indéfini. On ne peut utiliser que les
membres statiques de la classe et les paramètres du constructeur.
De plus, dans le cas d'un constructeur ou d'un destructeur,
l'exception attrapée est relancée si le flot de contrôle atteint la
fin du handler.
--
Franck Branjonneau <fasbjx@free.fr>
Je viens de me rendre compte que ce code est encore plus incorrect que ce que j'imaginais : quand on est dans le bloc "catch", si je ne m'abuse, l'objet de classe S n'a jamais existé.
En fait, la norme dit que toute partie correctement construite est détruite à l'entrée du handler.
Donc, parler du membre p1 (ou p2 ou p3) n'a aucun sens.
Oui c'est du comportement indéfini. On ne peut utiliser que les membres statiques de la classe et les paramètres du constructeur.
De plus, dans le cas d'un constructeur ou d'un destructeur, l'exception attrapée est relancée si le flot de contrôle atteint la fin du handler. -- Franck Branjonneau