[C++] membre static, pb de compilation

Résolu/Fermé
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 29 nov. 2006 à 13:03
 10di& - 30 juil. 2007 à 15:25
bonjour,
J'ai DevCpp 4.9.8, et je rencontre le problème suivant :
Le code qui suis compile et s'execute parfaitement:
struct eau
    {
    static const double a=12;
    static const double b[3]={0,1,2};
    static double P2TD(double T,double D)
        {double c;
        b[0];
        (a*eau::b[0]);
        return c;}
    };
int main()
    {
    double P=eau::P2TD(325,456);
    eau::b[0];
    return 0;
    }
En revanche, si je modifie légèrement celui ci de la façon suivante :
struct eau
    {
    static const double a=12;
    static const double b[3]={0,1,2};
    static double P2TD(double T,double D)
        {double c;
        c=b[0];
        (a*eau::b[0]);
        return c;}
    };
int main()
    {
    double P=eau::P2TD(325,456);
    eau::b[0];
    return 0;
    }
le compilateur me renvoi l'erreur :
l.13 : undefined reference to `eau::b'
Donc si quelqu'un pouvai me dire ce qui se passe...
Si ça se passe chez lui aussi.

6 réponses

mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
29 nov. 2006 à 16:49
  1 struct eau
  2 {
  3     static const double a=12;
  4     static const double b[3]={0,1,2};
  5     static double P2TD(double T,double D){
  6         double c;
  7         c=eau::b[0];
  8         (a*eau::b[0]); // inutile ?
  9         return c;
 10     }
 11 };
 12
 13 int main()
 14 {
 15     double P=eau::P2TD(325,456);
 16     eau::b[0]; // inutile ?
 17     return 0;
 18 }

Chez moi ca ne compile pas et pour moi ton code ne veut pas dire grand chose :
(mando@silk) (~) $ g++ plop.cpp
plop.cpp:4: error: a brace-enclosed initializer is not allowed here before '{' token
plop.cpp:4: error: invalid in-class initialization of static data member of non-integral type 'const double [3]'
plop.cpp: In static member function 'static double eau::P2TD(double, double)':
plop.cpp:7: error: 'b' is not a member of 'eau'
plop.cpp:8: error: 'b' is not a member of 'eau'
plop.cpp: In function 'int main()':
plop.cpp:16: error: 'b' is not a member of 'eau'

Je n'ai pas compris ce que tu veux faire, en particulier, aux lignes :
(a*eau::b[0]);
...
eau::b[0];

Ces deux instructions ne font a priori... rien :)
Enfin je n'ai pas compris l'intérêt du struct eau... Ce n'est pas plutôt un namespace que tu veux créer ?

Bonne chance
1
Char Snipeur
29 nov. 2006 à 21:40
Salut.
Merci pour ta réponse.
Par contre, ton compilateur te renvoie des messages un peu plus cohérent.
Ce que je voulais faire est historique. Je voulais créer une classe eau, qui permet de calculer les propriétes physique de l'eau. Le calcul ce fait sur plusieurs fonctions différentes, et avec des variables qui passent de l'une à l'autre. Bref, j'ai essayer, j'ai planter et je me suis démerder.
Et maintenant, je me disait que mon problème aurai pu être résolue grace à "static"... Donc, mon but est de regarder comment utilisé ce mot clé, et notament de faire un tableau de double en static.
Ce qui ne semble pas fonctionner.
Les instructions :
(a*eau::b[0]);
et
eau::b[0];
Sont là pour réaliser un appel à eau::b[0], pour voir si ça fonctionne : si j'ai bien compris le livre, lorsque tu tape "1+3+8*9+6;" le calcul est bien effectué, mais comme il n'est pas assigné à une variable ou afficher, c'est COMME SI tu ne fesait rien.
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
30 nov. 2006 à 08:52
Bon je pense que tu n'as pas bien compris à quoi servait le mot clé static. Alors pour static il y a deux utilisations :
1) pour des membres de classes (variables)
2) pour des méthodes

1) Pour les membres de classe :

Il s'agit d'un membre partagé en commun par toutes les instances de cette classe. C'est à dire que si tu la modifies dans un objet de cette classe ça va la corriger dans tous les autres objets de ce type. C'est une sorte de variable globale dont la portée est limitée à la classe.

Exemple d'utilisation : compter le nombre d'instance de classe :
#include <iostream>

class plop{
protected:
  static unsigned int nb_instance_plop=0;
  int x;
public;
  plop(int x0):x(x0){
    ++nb_instance_plop;
    std::cout << nb_instance_plop << "eme instance 'plop'" << std::endl
  }
};

int main(){
  plop p1(10);
  plop p2(6);
  plop p3(9);
  return 0;
}

2) Méthodes static

Tu peux avoir envie de rattacher une fonction à une structure sans que pour autant celle-ci se raccroche à une instance de la classe (this->) car cette méthode n'utilise aucun attribut de l'instance. Exemple.
#include <iostream>

class plop(){
  protected:
  unsigned int x;
  public:
  plop(unsigned int x0):x(x0){}
  static inline void nom_classe(){
    std::cout << "plop" << std::endl;
  }
};

int main(){
  plop p1(69);
  plop::nom_classe();
  return 0;
}


Ce que je voulais faire est historique. Je voulais créer une classe eau, qui permet de calculer les propriétes physique de l'eau. Le calcul ce fait sur plusieurs fonctions différentes, et avec des variables qui passent de l'une à l'autre.

J'ai rien compris ! Donne moi un exemple.

Sont là pour réaliser un appel à eau::b[0], pour voir si ça fonctionne : si j'ai bien compris le livre, lorsque tu tape "1+3+8*9+6;" le calcul est bien effectué, mais comme il n'est pas assigné à une variable ou afficher, c'est COMME SI tu ne fesait rien.

Effectivement le calcul est fait mais le résultat n'est stocké ni utilisé nul part donc l'instruction ne sert à rien (à part ralentir le programme :p)
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
30 nov. 2006 à 13:10
Salut.
Merci pour ta réponse, j'avai bien compris l'utilisation de static. Le seul problème c'est que je me heurte à des problèmes pratique de compilation.
Mais après divers tests, j'ai trouvé la règle:
Il est possible d'inialisé une variable static dans la class SI elle est const.
Si elle n'est pas const ou que c'est un tableau, alors il faut le faire en dehors de la class.
struct eau
    {
    static const double a=12;
    static double e;
    static const double b[3];//={0,1,2};
    static double P2TD(double T,double D)
        {double c;
        c=b[0];
        c=(a*eau::b[0]);
        return c;}
    };
static double abc=125;
int main()
    {
    double a=eau::e;
    double P=eau::P2TD(325,456);
    double tab[3]={0,1,2};
    tab[0]=eau::b[0];
    return 0;
    }
double eau::e=3;
const double eau::b[3]={0,1,2};
ce code compilera sans pb.
En revanche,
struct eau
    {
    static double a=0;
    }

ne compile pas, le compilateur me renvoie l'erreur qu'en iso C++ il est interdit d'initialisé un membre static .
chez moir ton "static unsigned int nb_instance_plop=0;" ne compil pas et me renvoie l'erreur :
ISO C++     forbids in-class initialization of non-const static member `nb_instance_plop'

La seul chose que je n'ai pas compris, c'est le pourquoi de la règle que j'ai énoncé...

Sinon, je pensai qu'il est possible d'utiliser un namespace comme une classe purement static ? (en quelque sorte.)
Par exemple, dans mon cas de calculer les proprietes de l'eau, avoir un class eau est ridicule, car un seul objet est suffisant, donc remplacer struct par namespace est plus aproprié.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
30 nov. 2006 à 14:54
Tu as raison je me suis trompée, dans ce cas précis la variable static est en fait interne à la fonction (ou doit rester const) :
#include <iostream>

class plop{
  protected:
  unsigned int x;
  public:
  plop(unsigned int x0):x(x0){
      static unsigned int nb_instance_plop = 0;
      ++nb_instance_plop;
      std::cout << nb_instance_plop << "eme instance 'plop'" << std::endl;
  }
  static inline void nom_classe(){
    std::cout << "plop" << std::endl;
  }
};

int main(){
  plop p1(69);
  plop p2(28);
  plop p3(47);
  plop::nom_classe();
  return 0;
}

Dans ton cas il suffit de faire :
#include <iostream>
namespace eau{
    unsigned int a = 56;
}

int main(){
  std::cout << a::eau << std::endl;
  return 0;
}

Bonne chance
0
Il est possible d'initialiser un membre const static SI il est de type int !

static const int i = 0; //Fonctionne
static const double d = 0.0;//Fonctionne pas

http://c.developpez.com/faq/cpp/?page=static#CLASS_static_const
-1