OVH Cloud OVH Cloud

fonction 'static'

31 réponses
Avatar
Michaël Delva
Bonjour à tous,

j'ai une classe avec des fonctions en 'static'

Je suis obligé d'écrire l'implémentation de ces fonctions dans le même
fichier que leur déclaration?

Merci d'avance...

10 réponses

1 2 3 4
Avatar
Michel Michaud
Dans news:,
j'ai une classe avec des fonctions en 'static'

Je suis obligé d'écrire l'implémentation de ces fonctions dans
le même fichier que leur déclaration?


Non. Tu as essayé ?

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
Horst Kraemer
On 20 May 2004 14:25:30 GMT, "Michaël Delva"
wrote:

Bonjour à tous,

j'ai une classe avec des fonctions en 'static'

Je suis obligé d'écrire l'implémentation de ces fonctions dans le même
fichier que leur déclaration?


Non. Tu les fais comme d'habitude

//toto.h
#ifndef TOTO_H
#define TOTO_H
struct X
{
static void f();
};
#endif


//toto.cpp
#include "toto.h"
void X::f() {}

//main.cpp
#include "toto.h"
int main()
{
X::f();
}

--
Horst

Avatar
Anthony Fleury
Michaël Delva wrote:

Bonjour à tous,

j'ai une classe avec des fonctions en 'static'

Je suis obligé d'écrire l'implémentation de ces fonctions dans le même
fichier que leur déclaration?


Pas du tout, et un simple test aurait évité d'attendre la réponse d'une
personne exterieure.
Il ne faut pas confondre fonctions static, qui par héritage du C sont des
fonctions dont la portée se réduit au fichier en cours, et fonctions
membres static, qui sont elles des fonctions indépendante de toute instance
de la classe. La définition d'une telle fonction peut se faire à tout
endroit où un membre non static de la classe peut être défini.

Anthony
--
"You could be my unintended, choice to live my life extended
You should be the one I'll always love, I'll be there as soon as I can
But I'm busy mending broken pieces of the life I had before"
(C) Muse - Unintended

Avatar
Michaël Delva
J'ai testé ;-)

Voici mon fichier H

#ifndef Base64H
#define Base64H

#include <vector>
#include <string>

class Base64
{
static char Encode(unsigned char uc);
static unsigned char Decode(char c);
static bool IsBase64(char c);
public:
static std::string Encode(const std::vector<unsigned char> & vby);
static std::vector<unsigned char> Decode(const std::string & str);
};

#endif

Les implémentations des fonctions sont dans le CPP (Example d'une fonction)

inline char Base64::Encode(unsigned char uc)
{
if (uc < 26)
return 'A'+ uc;

if (uc < 52)
return 'a'+ (uc - 26);

if (uc < 62)
return '0'+ (uc - 52);

if (uc == 62)
return '+';

return '/';
};



Quand dans une autre classe je fais:

//....
#include "Base64.h"
//....

void MaFonction()
{
std::string result = Base64::Encode(vect);
}

J'ai le message suivant à la liaison (Avec Borland):

[Lieur Erreur] Unresolved external 'Base64::Encode(const _STL::vector
<unsigned char, _STL::allocator<unsigned char> >&)' referenced from D:
BORLANDCBUILDER6PROJECTSUNIT1.OBJ

Par contre si je mets les implémentations dans le H, tout fonctionne
correctement...

D'où vient le problème?
Avatar
Anthony Fleury
Michaël Delva wrote:

J'ai testé ;-)

Les implémentations des fonctions sont dans le CPP (Example d'une
fonction)

inline char Base64::Encode(unsigned char uc)
{


Une fonction inline voit sa portée limitée au fichier en cours, donc il faut
qu'elle soit définie dans le .h


D'où vient le problème?


du inline.

Anthony
--
"You could be my unintended, choice to live my life extended
You should be the one I'll always love, I'll be there as soon as I can
But I'm busy mending broken pieces of the life I had before"
(C) Muse - Unintended

Avatar
Michel Michaud
Dans news:,
J'ai testé ;-)

class Base64
{
static char Encode(unsigned char uc);
static unsigned char Decode(char c);


[...]
Les implémentations des fonctions sont dans le CPP (Example
d'une fonction)

inline char Base64::Encode(unsigned char uc)


Enlève le inline ! Si tu veux inline il faut l'implémentation
dans le .h. Ça n'a rien à voir avec le static... (bien
que les récentes règles de « linkage » soient particulières)

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
Michaël Delva
D'où vient le problème?


du inline.

Anthony


Effectivement... ;-)

Merci beaucoup


Avatar
Michel Michaud
Dans news:40acef68$0$21569$, Anthony
Michaël Delva wrote:

J'ai testé ;-)

Les implémentations des fonctions sont dans le CPP (Example
d'une fonction)

inline char Base64::Encode(unsigned char uc)
{


Une fonction inline voit sa portée limitée au fichier en cours,
donc il faut qu'elle soit définie dans le .h


Pas vraiment il me semble, en tout cas pas pour les fonctions
libres où le inline laisse le « external linkage »...

Mais comme ça ne fonctionne pas pour Michaël, soit ce n'est pas
le cas pour les fonctions membres, soit son compilateur n'est
pas à jour. Je n'ai pas le temps de vérifier ce cas dans la
norme, mais à tout le moins, ceci devrait fonctionner :

// A.cpp
inline void A()
{}

// B.cpp
void A();

int main()
{
A();
}

Évidemment, il est possible que le inline ne soit pas
respecté au niveau de la génération du code...

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/


Avatar
Fabien LE LEZ
On Thu, 20 May 2004 17:30:14 +0200, Anthony Fleury
wrote:

Pas du tout, et un simple test aurait évité d'attendre la réponse d'une
personne exterieure.


Un "simple test" aurait permis de savoir comment se comporte son
compilateur. Ce n'est pas tout à fait la même chose, même si ça donne
une idée de la réponse.

--
;-)
FLL, Epagneul Breton

Avatar
Anthony Fleury
Michel Michaud wrote:

Dans news:40acef68$0$21569$, Anthony

Une fonction inline voit sa portée limitée au fichier en cours,
donc il faut qu'elle soit définie dans le .h


Pas vraiment il me semble, en tout cas pas pour les fonctions
libres où le inline laisse le « external linkage »...

Mais comme ça ne fonctionne pas pour Michaël, soit ce n'est pas
le cas pour les fonctions membres, soit son compilateur n'est
pas à jour. Je n'ai pas le temps de vérifier ce cas dans la
norme, mais à tout le moins, ceci devrait fonctionner :



Dans la norme ok, mais dans la pratique je n'ai vu que des compilateurs qui
avaient un comportement qui faisait que inline entrainait static, c'est à
dire réduction de la portée de la fonction.

bash-2.05b$ g++ --version
g++ (GCC) 3.2.3
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

bash-2.05b$ cat a.cpp b.cpp
/* a.cpp */

inline void A() {
}

/* b.cpp */

void A();

int main() {
A();
}
bash-2.05b$ g++ a.cpp b.cpp
/tmp/cckOGwEL.o(.text+0x11): In function `main':
: undefined reference to `A()'
collect2: ld returned 1 exit status
bash-2.05b$

C'est aussi le cas sur Visual C++ 5 et 6 sur lesquels j'ai travaillé.
Dans ce cas comme dans le cas des templates je prend donc l'habitude de
créer des fichiers ayant une extension autre (.Tpp et .inl) et je les
inclus dans les .cpp.

À noter que je n'ai jamais testé comeau mais tous ces codes doivent passer
sous Comeau bien sûr.

Anthony
--
"You could be my unintended, choice to live my life extended
You should be the one I'll always love, I'll be there as soon as I can
But I'm busy mending broken pieces of the life I had before"
(C) Muse - Unintended


1 2 3 4