2009-05-22 10 views
1

Je rencontre un problème lors de l'accès à une variable const statique définie dans la section de variable de membre private de ma classe. Plus précisément, le code écrit ci-dessous peut générer la variable dans le constructeur, mais lorsque j'essaie d'y accéder via une fonction accesseur, j'obtiens une erreur discutée ci-dessous. Si quelqu'un sait pourquoi j'apprécierais votre aide.Problème lors de l'accès aux variables const statiques via les fonctions de membre de classe

#include <iostream> 
using namespace std; 

class TestStaticVariables 
{ 
// Private member variable: 
static const double static_double_variable; 
public: 
// Constructor: 
TestStaticVariables() 
{ 
    // Initialization: 
    static const double static_double_variable = 20.0; 
    cout << static_double_variable; 
} 
// Member Function: 
void test(); 
}; 

void TestStaticVariables::test() 
{ 

Lorsque cette ligne suivante est décommentée je reçois le message d'erreur suivant:

Ligne Lieu Outil: 0: "TestStaticVariables :: static_double_variable", référencé à partir de:

//cout << static_double_variable; 
} 

int main(int argc, char* const argv[]) 
{ 

TestStaticVariables test_instance; 

return 0; 
} 

Répondre

9

Essayez d'initialiser le variable en dehors de la définition de la classe, voici un exemple de travail:

#include <iostream> 

class Foo { 
    static const double _bar; 

public: 
    Foo(); 

    void Bar(); 
}; 

const double Foo::_bar = 20.0; 

Foo::Foo() { 
    std::cout << Foo::_bar << std::endl; 
} 

void Foo::Bar() { 
    std::cout << Foo::_bar << std::endl; 
} 

int main(int argc, char *argv[]) { 
    Foo f; 
    f.Bar(); 

    return 0; 
} 
+0

Raison pour laquelle cela fonctionne? – nbro

2

Ce que vous avez marqué comme "// Initialisation" est en fait une création et une initialisation d'une deuxième variable avec le même nom, dans une portée différente. La variable static_double_variable créée dans le constructeur est une variable locale dans le constructeur, et ne fait pas référence à la variable statique de niveau classe portant le même nom.

Ce que vous devez faire pour éviter cela est de simplement supprimer les informations de type pour que ce soit une déclaration normale plutôt que d'une initialisation, comme ceci:

// Initialization: 
    static_double_variable = 20.0; 

Mais bien sûr, cela ne fonctionnera pas en réalité parce que c'est une affectation à une variable const, et vous avez toujours un deuxième problème, qui est en fait ce qui cause l'erreur que vous voyez. Lorsque vous écrivez:

// Private member variable: 
static const double static_double_variable; 

Vous déclarez qu'une telle variable existera. Cependant, vous ne définissez pas réellement cette variable (c'est-à-dire, demandez au compilateur de créer un espace de stockage pour cette variable).

Pour ce faire, et fixer les deux vos problèmes en dehors de votre class { } construction, vous pouvez écrire:

const double TestStaticVariables::static_double_variable = 20.0; 

Cette fois définit la variable et donne une première valeur constante.

Dans le cas qui était peu claire, cette question est également décrit succinctement dans le C++ FAQ: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.10

2

Ce que vous faites dans le constructeur est cacher la variable membre. Vous devez initialiser static_double_variable en dehors de la déclaration de classe.

1

Votre constructeur déclare et définit une variable statique locale, qui a le même nom que la variable membre static de la classe. La variable locale masque le membre de la classe.

C'est ce que vous pouvez voir dans le constructeur. Ensuite, lorsque vous essayez de lier le membre de la classe dans l'autre méthode, l'éditeur de liens découvre qu'il est déclaré mais non défini, donc il abandonne.

Vous ne devriez probablement pas initialiser de toute façon un membre de classe statique dans un constructeur, car il n'y a qu'une seule variable pour la classe, mais le constructeur est appelé une fois pour chaque instance.Vous devez définir la variable en dehors de toute fonction (ou seulement dans la déclaration, sauf si vous voulez cacher la valeur aux utilisateurs de votre API).

Questions connexes