2009-05-22 12 views
1

Ich habe ein Problem beim Zugriff auf eine statische const-Variable, die im Abschnitt private Membervariable der Klasse definiert ist. Insbesondere kann der unten geschriebene Code die Variable innerhalb des Konstruktors ausgeben, aber wenn ich versuche, über eine Accessor-Funktion darauf zuzugreifen, bekomme ich einen Fehler, der unten diskutiert wird. Wenn jemand weiß, warum ich Ihre Hilfe zu schätzen weiß.Problem beim Zugriff auf statische const-Variablen über Klassenmemberfunktionen

#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() 
{ 

Wenn diese nächste Zeile ist uncommented ich die folgende Fehlermeldung erhalten:

Linie Location Tool: 0: "TestStaticVariables :: static_double_variable", verwiesen von:

//cout << static_double_variable; 
} 

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

TestStaticVariables test_instance; 

return 0; 
} 

Antwort

9

Versuchen Sie, die Initialisierung Variable außerhalb der Klassendefinition, hier ein Arbeitsbeispiel:

#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

Warum funktioniert das? – nbro

2

Was Sie als "// Initialisierung" markiert haben, ist das Erstellen und Initialisieren einer zweiten Variablen mit demselben Namen in einem anderen Bereich. Die Variable static_double_variable, die im Konstruktor erstellt wird, ist eine lokale Variable im Konstruktor und bezieht sich nicht auf die statische Variable auf Klassenebene mit demselben Namen.

Was Sie tun müssen, um dies zu vermeiden ist es, einfach die Typinformationen zu entfernen, so dass es eine normale Aussage ist eher als eine Initialisierung, etwa so:

// Initialization: 
    static_double_variable = 20.0; 

Aber natürlich wird dies nicht wirklich funktionieren, weil Es ist eine Zuweisung zu einer const-Variablen, und Sie haben immer noch ein zweites Problem, was meiner Meinung nach tatsächlich den Fehler verursacht, den Sie sehen. Wenn Sie schreiben:

// Private member variable: 
static const double static_double_variable; 

Sie deklarieren, dass eine solche Variable vorhanden sein wird. Sie definieren diese Variable jedoch nicht (d. H. Weisen den Compiler an, Speicher dafür zu erstellen).

Um das zu tun, und beheben sowohl Ihre Fragen außerhalb Ihres class { } Konstrukt, würden Sie schreiben:

const double TestStaticVariables::static_double_variable = 20.0; 

Dies sowohl die Variable definiert und es gibt eine anfängliche, konstanten Wert.

Im Fall, dass unklar war, wird dieses Problem auch kurz und bündig in der C++ FAQ beschrieben: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.10

2

Was Sie im Konstruktor tut Variable das Mitglied versteckt ist.
Sie müssen die static_double_variable außerhalb der Klassendeklaration initialisieren.

1

Ihr Konstruktor deklariert und definiert eine lokale statische Variable, die zufälligerweise denselben Namen wie die statische Klassenmitgliedsvariable hat. Die lokale Variable verbirgt das Klassenmitglied.

Dies ist, was Sie im Konstruktor sehen können. Wenn Sie dann versuchen, eine Verknüpfung mit dem Klassenmember in der anderen Methode herzustellen, stellt der Linker fest, dass er deklariert, aber nicht definiert ist, sodass er aufgibt.

Wahrscheinlich sollten Sie ein statisches Klassenmitglied in einem Konstruktor sowieso nicht initialisieren, da es nur eine Variable für die Klasse gibt, aber der Konstruktor für jede Instanz einmal aufgerufen wird.Sie sollten die Variable außerhalb jeder Funktion (oder nur in der Deklaration definieren, es sei denn, Sie möchten den Wert von Benutzern Ihrer API verbergen).

Verwandte Themen