OVH Cloud OVH Cloud

peut-on définir une fonction membre statique dans un fichier .cpp ?

35 réponses
Avatar
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.

Quelqu'un a déjà vu/utilisé ce genre de choses ?

Aurélien.

5 réponses

1 2 3 4
Avatar
Fabien LE LEZ
On Sun, 16 Oct 2005 20:23:06 +0200, Franck Branjonneau
:

il est des cas où ce n'est pas
vrai.


Euh... J'ai du mal à comprendre, là. Tu veux dire que la règle que
j'ai citée n'est pas vraie dans des programmes erronés ?

Finalement, peux-tu me proposer un bout de code correct qui utilise
cette fonctionnalité à bon escient ?

Je t'avoue que je suis assez peu au fait des subtilités de
try...catch : j'ai tendance à écrire beaucoup de "throw" et très peu
de try...catch.

Avatar
Franck Branjonneau
Fabien LE LEZ écrivait:

On Sun, 16 Oct 2005 20:23:06 +0200, Franck Branjonneau
:

il est des cas où ce n'est pas
vrai.


Euh... J'ai du mal à comprendre, là. Tu veux dire que la règle que
j'ai citée n'est pas vraie dans des programmes erronés ?


Non. Tu dis que si un constructeur ne peut pas construire
un de ses sous-objets (classe de base, membre), il libère ses
ressources et fait suivre les exceptions.

Je dis oui en général. Mais que parfois il a un recours comme dans

template< char const * _default= "" >
struct Message {

char const * const instance_;


Message(
char const * const instance):
instance_(copy(new(std::nothrow) char[std::strlen(instance)+1], instance)) {

}



char const *
copy(
char * const target,
char const * const source)
throw() {

return target != 0 ? std::strcpy(target, source) : _default;
}

}; struct Message< _default >



extern char const default_[]= "Default";

int
main() {

S().foo();

for(;;) {

std::cout << Message< default_ >("Test").instance_ << "n";
}

return 0;
}


Je t'avoue que je suis assez peu au fait des subtilités de
try...catch : j'ai tendance à écrire beaucoup de "throw" et très peu
de try...catch.



Pour les try/catch, j'utilise souvent la forme avec le try/catch "à
l'extérieur" avec les destructeurs

~S() try { /* ... */ } catch(...) { assert(false); }

Pour autant que je sache, ça ne change rien par rapport à la forme
avec le try/catch "à l'intérieur".

J'étais persuadé qu'il en était de même avec les constructeurs ;
j'étais dans l'erreur.
--
Franck Branjonneau


Avatar
kanze
Fabien LE LEZ wrote:
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 ?


Non. J'ai appris le C++ avant que ce mécanisme existait. Je
continue à programmer comme s'il n'existe pas.

Si oui, pourrais-tu me donner un exemple réel ?


Réel, dans quel sens. Moi, je n'en ai jamais eu besoin. Ça ne
veut pas dire que le besoin ne peut pas exister. Considère, par
exemple, un cas où je veux que tout le constructeur s'exécute
avec un lock. Alors je triche un peu :

MaClasse::MaClasse()
try {
: premierElemOuBase( acquiertLock(), ... )
{
// reste de l'initialisation...
libereLock() ;
}
} catch ( ... ) {
libereLock() ;
throw ;
}

Et, accessoirement, que penses-tu de
<http://www.gotw.ca/gotw/066.htm> (ou les items 17 et 18 de
"More exceptional C++") ?


Qu'est-ce qu'il y a à penser ? Il décrit bien le C++, comment il
fonctionne. Je trouve qu'ici, le C++ a bien fait comme il faut.
Je n'ai rien à dire de plus.

--
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


Avatar
Fabien LE LEZ
On 17 Oct 2005 00:44:36 -0700, "kanze" :

T'arrive-t-il d'utiliser ce mécanisme ?


Non. J'ai appris le C++ avant que ce mécanisme existait.


Tu as bien appris le C++ avant l'apparition des GC...

Réel, dans quel sens.


C'est-à-dire, est-ce que quelqu'un sur fra est capable de me dire
"Oui, j'ai utilisé ce mécanisme [à bon escient] dans un de mes
programmes."

Qu'est-ce qu'il y a à penser ?


Si j'ai bien compris son propos, l'utilité du mécanisme des "try/catch
externes" est infinitésimale.


Avatar
kanze
Fabien LE LEZ wrote:
On 17 Oct 2005 00:44:36 -0700, "kanze" :

T'arrive-t-il d'utiliser ce mécanisme ?


Non. J'ai appris le C++ avant que ce mécanisme existait.


Tu as bien appris le C++ avant l'apparition des GC...


:-) La différence, c'est que le GC apporte une amélioration
réele et importante dans ma productivité.

Réel, dans quel sens.


C'est-à-dire, est-ce que quelqu'un sur fra est capable de me
dire "Oui, j'ai utilisé ce mécanisme [à bon escient] dans un
de mes programmes."

Qu'est-ce qu'il y a à penser ?


Si j'ai bien compris son propos, l'utilité du mécanisme des
"try/catch externes" est infinitésimale.


Disons que je m'en tire très bien sans l'utiliser. Mais ça ne
veut pas dire que d'autres n'en trouve pas d'utilité. C'est
certainement moins utile que le GC.

--
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



1 2 3 4